1. Excel 导出
/// <summary>
/// 导出Excel
/// </summary>
/// <returns></returns>
public async Task<IActionResult> ExportExcel( )
{
//获取数据
var data = await GetData();
// 创建一个Excel工作簿
IWorkbook workbook = new XSSFWorkbook();
// 创建一个工作表
ISheet sheet = workbook.CreateSheet("sheet名称");
// 创建第一行
var oneRow = sheet.CreateRow(0);
//创建第一行的第一个单元格并设置单元格的值
// 可以填充包含换行的字符串 例子 :string multiLineText = "第一行\n第二行\n第三行";
oneRow.CreateCell(0).SetCellValue("test");
//合并单元格 AddMergedRegion参数分别是(起始行,结束行,起始列,结束列)
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, 33));
//设置单元格样式
var cellStyle = SetCellStyle(workbook, true,false);//此方法见下面内容
// 将样式应用于单元格
oneRow.RowStyle = cellStyle;
// 设置列宽
// 设置第0列的宽度为15个字符的宽度,256是字符宽度的单位
sheet.SetColumnWidth(0, 15 * 256);
//设置单元格样式
var cellStyle1 = SetCellStyle(workbook, false,false);//此方法见下面内容
// 填充数据
int rowIndex = 3;
foreach (var item in list)
{
//填充你的数据......
// 将样式应用于单元格
numRow.RowStyle = cellStyle1;
//设置单元格样式 //此方法见下面内容
var cellStyle2 = SetCellStyle(workbook, false, true, "#FFB3CA");
//创建单元格
var cell = numRow.CreateCell(15);
// 将单元格样式应用到单元格
cell.CellStyle = cellStyle2;
// 设置单元格的值
cell.SetCellValue("你的value");
}
//合并单元格
MergedRegion(data, sheet);//此方法见下面内容
// 保存Excel文件
var memoryStream = new MemoryStream();
workbook.Write(memoryStream);
// 在保存之后关闭MemoryStream
memoryStream.Close();
// 重新打开MemoryStream并设置位置
memoryStream = new MemoryStream(memoryStream.ToArray());
// 设置位置为流的开头
memoryStream.Seek(0, SeekOrigin.Begin);
// 返回Excel文件 //注意:如果File报错, 将当前类继承ControllerBase即可
return File(memoryStream, "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet", "Demo.xlsx");
}
2. SetCellStyle()方法 设置单元格样式
/// <summary>
/// 设置单元格样式
/// </summary>
/// <param name="workbook"></param>
/// <param name="isBold"></param>
/// <returns></returns>
public static ICellStyle SetCellStyle(IWorkbook workbook, bool isBold, string? colorHex = null)
{
// 创建单元格样式并设置文本居中
XSSFCellStyle cellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
cellStyle.Alignment = HorizontalAlignment.Center;
cellStyle.VerticalAlignment = VerticalAlignment.Center;
//单元格自动换行
cellStyle.WrapText = true;
if (isBold == true)
{
// 创建字体并设置为粗体
var font = workbook.CreateFont();
// 设置字体为粗体
font.IsBold = true;
//应用字体
cellStyle.SetFont(font);
}
// 使用正则表达式来匹配有效的十六进制颜色值
string pattern = @"^#([0-9A-Fa-f]{6})$";
if (colorHex != null&& Regex.IsMatch(colorHex, pattern))
{
//将十六进制颜色值转换为RGB
var customColorRgb = HexToBytes(colorHex);
XSSFColor xssfColor = new XSSFColor();
//设置自定义颜色
xssfColor.SetRgb(customColorRgb);
//应用自定义颜色
cellStyle.FillForegroundColorColor = xssfColor;
// 设置填充模式为实心
cellStyle.FillPattern = FillPattern.SolidForeground;
}
// 设置单元格的边框样式
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
return cellStyle;
}
3. 将十六进制颜色值转换为RGB
/// <summary>
/// 将十六进制颜色值转换为 byte[] 数组
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
public static byte[] HexToBytes(string hex)
{
// 去除可能的#字符
hex = hex.TrimStart('#');
int hexValue = Convert.ToInt32(hex, 16);
byte red = (byte)((hexValue >> 16) & 0xFF);
byte green = (byte)((hexValue >> 8) & 0xFF);
byte blue = (byte)(hexValue & 0xFF);
return new byte[] { red, green, blue };
}
4.合并单元格
/// <summary>
/// 合并单元格
/// </summary>
/// <param name="data"></param>
/// <param name="sheet"></param>
public static void MergedRegion(List<"你的类型"> data, ISheet sheet,)
{
int startRow = 3;
int index = 1;
for (int i = 0; i < data?.Count; i++)
{
int pre = data[i].valueList.Count;
if (data[i].valueList?.Count == 1)
{
pre--;
}
if (data != null && data[i].valueList?.Count > 1)
{
for (int j = 0; j <= 8; j++)
{
//合并单元格
sheet.AddMergedRegion(new CellRangeAddress(startRow, startRow + pre - 1, j, j));
}
index++;
}
else
{
startRow++;
index++;
}
startRow = startRow + pre;
if (data.Count + 2 >= startRow)
{
//获取行号、获取当前行的单元格、并设置单元格的值//
sheet.GetRow(startRow).GetCell(0).SetCellValue(index);
}
}
}
导入Excel
/// <summary>
/// 导入Excel
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public IActionResult ImportExcel(IFormFile file)
{
if (file == null || file.Length == 0)
{
return BadRequest("未上传文件");
}
using (var stream = file.OpenReadStream())
{
IWorkbook workbook = new XSSFWorkbook(stream);
// 第一个工作表
ISheet sheet = workbook.GetSheetAt(0);
// 第一行作为标题行
IRow headerRow = sheet.GetRow(0);
// 处理Excel数据
for (int i = (sheet.FirstRowNum + 3); i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
if (row != null)
{
// 处理行数据
for (int j = 0; j < row.LastCellNum; j++)
{
ICell cell = row.GetCell(j);
// 如果单元格在合并单元格范围内,找到合并单元格的首个单元格
if (cell != null && cell.IsMergedCell)
{
//此方法见下面内容
int mergedRegionIndex = GetMergedRegionIndex(sheet, i, j);
if (mergedRegionIndex >= 0)
{
var mergedRegion = sheet.GetMergedRegion(mergedRegionIndex);
int firstRow = mergedRegion.FirstRow;
int firstCol = mergedRegion.FirstColumn;
cell = sheet.GetRow(firstRow).GetCell(firstCol);
}
}
// 处理单元格数据
if (cell != null)
{
string cellValue = cell?.ToString();
// 处理逻辑......
}
}
}
}
}
return Ok("Excel导入成功!");
}
查找合并单元格的首个单元格
/// <summary>
/// 查找合并单元格的首个单元格
/// </summary>
/// <param name="sheet"></param>
/// <param name="rowNum"></param>
/// <param name="colNum"></param>
/// <returns></returns>
public int GetMergedRegionIndex(ISheet sheet, int rowNum, int colNum)
{
for (int i = 0; i < sheet.NumMergedRegions; i++)
{
var mergedRegion = sheet.GetMergedRegion(i);
if (rowNum >= mergedRegion.FirstRow && rowNum <= mergedRegion.LastRow
&& colNum >= mergedRegion.FirstColumn && colNum <= mergedRegion.LastColumn)
{
return i;
}
}
return -1;
}
博客主要围绕Excel的导出与导入展开。导出部分涉及SetCellStyle方法设置单元格样式、十六进制颜色转RGB及合并单元格;导入部分提及查找合并单元格的首个单元格,为Excel操作提供了技术参考。
3506

被折叠的 条评论
为什么被折叠?



