• Npoi--合并单元格


    一、缘由。

        最近公司的一个需求,导出 Excel, 相同的数据进行合并,并且 还有 二级合并。

      最终效果图如下:

      

    哈哈哈哈哈,图表略微有些丑陋,请大家不要介意。

    他的原始数据,是一条一条的,

    如下图:

      

    二、导出 处理 逻辑。

      

        

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

      重写 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();
            }
        }

    合并 单元格 方法。

      

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

      

    至此 ,合并结束。 

    小记:

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

      

    以上,如果 有好的建议 欢迎 指正。

  • 相关阅读:
    校园导游图的课程设计(三)
    校园导游图的课程设计(二)
    vim中Mapping already in use: "<LocalLeader>is", mode "n"错误解决的方法解释
    fedora 的截图快捷键
    校园导游图的课程设计(一)
    theos(一)
    脱壳
    初识Mach-O
    Cycript(二)
    Cycript(一)
  • 原文地址:https://www.cnblogs.com/zyhbook/p/9614437.html
Copyright © 2020-2023  润新知