NPOI 基本使用教程

博客主要围绕Excel的导出与导入展开。导出部分涉及SetCellStyle方法设置单元格样式、十六进制颜色转RGB及合并单元格;导入部分提及查找合并单元格的首个单元格,为Excel操作提供了技术参考。

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; 
    }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值