Npoi--合并Excel单元格

1.导出 处理 逻辑。

			try
            {
                int propertyCount = getPropertyCount(typeof(T));

                var hssfWorkbook = new XSSFWorkbook();
                var sheet1 = hssfWorkbook.CreateSheet(sheetName);

                var row1 = (XSSFRow)sheet1.CreateRow(2);
                //表头样式
                var rowstyle = hssfWorkbook.CreateCellStyle();
                rowstyle.Alignment = HorizontalAlignment.Center;
                //rowstyle.FillBackgroundColor = HSSFColor.Grey25Percent.Index;
                var font1 = hssfWorkbook.CreateFont();

                font1.FontHeight = 20;
                //font1.Boldweight = 600;
                rowstyle.SetFont(font1);

                font1.FontHeightInPoints = 20;
                font1.Boldweight = 700;


                WriteHeader(typeof(T), row1, rowstyle);

                int i = 0;
                for (int j = 0; j < listData.Count; j++)
                {
                    int rowIndex = i;
                    var rowData = (XSSFRow)sheet1.CreateRow(rowIndex + 3);
                    WriteData(listData[j], typeof(T), rowData);
                    i++;
                }

                setAutoColumn(sheet1, i);
          //sheet1 就是 在内存中 填充好的 Excel数据。下面合并要用到

          ///
          ///这里 放置 合并方法。
          ///第 0 列  合并。  
          mergeuser(sheet1,0);

          

                var rowfooter = (XSSFRow)sheet1.CreateRow(i + 3);
                //NpoiMemoryStream 是 重写Npoi流方法
                using (NpoiMemoryStream ms = new NpoiMemoryStream())
                {
                    ms.AllowClose = false;
                    hssfWorkbook.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
                    hssfWorkbook = null;
                    return ms;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

2.重写 Npoi流。

	/// <summary>
    /// 重写Npoi流方法
    /// </summary>
    public class NpoiMemoryStream : MemoryStream
    {
        public NpoiMemoryStream()
        {
            AllowClose = true;
        }
        public bool AllowClose { get; set; }

        /// <summary>
        /// 关闭
        /// </summary>
        public override void Close()
        {
            if (AllowClose)
                base.Close();
        }
    }

3.合并 单元格 方法。

		private static void mergeuser(ISheet sheet, int columnIndex)
        {
       //开始 要合并的内容为空
            var previous = "";
       //startRow  是你Excel 数据是 第几行开始的
            var startRow = 3;
            for (int rowNum = 3; rowNum <= sheet.LastRowNum; rowNum++)
            {
          //获取 指定行,指定列的 数据内容
                var current = sheet.GetRow(rowNum).GetCell(columnIndex).StringCellValue;
          // 判断 获取到的内容是否和 上一列 相等
                if (current.Equals(previous))
                {continue;}
                else
                {
            // 第一级 合并。
            //将获取到的 内容 赋值到 previous 
                    previous = current;
            // 判断开始行,是否小于 循环的行数。
                    if (startRow < rowNum)
                    {
               //第二级 合并
                        var celltext = "";
                        var startAM = startRow;
                        for (int i = startRow; i <= rowNum; i++)
                        {
                            var endtext = sheet.GetRow(i).GetCell(1).StringCellValue;
                            if (celltext.Equals(endtext))
                            { continue; }
                            else
                            {
                                celltext = endtext;
                                if (startAM < i)
                                {
                      // CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
                      //这里 终止行号 -1  原因是:上面循环判断时 内容不一样的  才进行 合并,
                      //这时 行数 i 内容 已经不一样,所以 需要减去 1  进行合并

                                    sheet.AddMergedRegion(new CellRangeAddress(startAM, i - 1, columnIndex + 1, columnIndex + 1));
                                }
                    // 将 当前行数,进行赋值给 启始行数。
                                startAM = i;
                            }
                        }
                        sheet.AddMergedRegion(new CellRangeAddress(startRow, rowNum - 1, columnIndex, columnIndex));
                    }
                    startRow = rowNum;
                }
            }
        }

4.合并时 ,最好是在 添加内容 到 sheet 里面时,进行合并,这样的话,减少了 一次 循环所有数据的操作,提高了 速度问题

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要读取合并单元格的数据,需要使用 NPOI 库中的 CellRangeAddress 类来获取合并单元格的范围,并在处理每个单元格时判断它是否在合并单元格范围内。以下是一个简单的示例代码: ```csharp using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; // 打开 Excel 文件 using (FileStream fs = new FileStream("test.xlsx", FileMode.Open, FileAccess.Read)) { XSSFWorkbook workbook = new XSSFWorkbook(fs); ISheet sheet = workbook.GetSheetAt(0); // 遍历所有行 for (int i = 0; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; // 遍历所有列 for (int j = 0; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j); if (cell == null) continue; // 判断单元格是否在合并单元格范围内 bool isMerged = false; for (int k = 0; k < sheet.NumMergedRegions; k++) { CellRangeAddress range = sheet.GetMergedRegion(k); if (range.IsInRange(i, j)) { isMerged = true; break; } } // 如果单元格合并单元格范围内,则获取合并单元格的值 if (isMerged) { ICell firstCell = sheet.GetRow(range.FirstRow).GetCell(range.FirstColumn); Console.WriteLine(firstCell.ToString()); } else { Console.WriteLine(cell.ToString()); } } } } ``` 需要注意的是,由于合并单元格可能会跨越多行或多列,因此在判断单元格是否在合并单元格范围内时需要使用 CellRangeAddress 类的 IsInRange 方法。此外,如果单元格合并单元格范围内,则需要获取合并单元格的第一个单元格的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值