NPOI实现两级分组合并功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NPOI实现两级分组合并功能相关的知识,希望对你有一定的参考价值。

  NPOI版本:2.2.1.0

  最近公司有这样的需求:

  统计每个部门下面,多个费用使用情况。部门存在多级,但统计时,只需统计到2级,2级以下的,归到第2级的部门下。并且要求,第2级部门有个小计,第1级部门需要有个合计。最后,还需提供总计。

  本来对NPOI研究的还不够深入的,以前都是直接通过别人提供的代码来实现对DataTable中的数据进行全部导出,但里面不带合并,及合计功能,不满足当前需求。不得已,只有好好地研究一下了。还好,最终实现了要求。

  在此,也感谢其他提供相关资料的人员,让我实现了此功能。

 

  简要说明一下使用:

  1、Export2Template2方法直接使用。DataTable原始数据,必须是已经按要求排好序的数据。全部是逐行向下处理。

  2、要导出的列名,取自cellKeys中。列名必须为source中存在的。

  3、相同值合并的第1列,为cellKeys[0],合并的第2列,为cellKeys[1],如需要其它列的合并,可以此基础上,按自己的需求进行调整。(合并时,只会比较上下行的数据内容)

  4、要导出的数据中,数值类型,自动居右。其它类型,自动居中。

  5、小计,合计,总计的字体,全部加黑

  6、小计,合计,总计,自动对数值类型进行汇总。其它类型数据全部置空。

  7、合并的列数:mergeColumns。如果>2,自动只处理前2列。如果<1,则不做合并处理。

 

  废话少话,直接上可用的代码:

        /// <summary>
        /// 根据模版导出Excel -- 特别处理,每个分组带合计
        /// </summary>
        /// <param name="source">源DataTable</param>
        /// <param name="cellKeys">需要导出的对应的列字段  例:string[] cellKeys = { "Date","Remarks" };</param>
        /// <param name="strFileName">要保存的文件名称(包含后缀)  例:"要保存的文件名.xls"</param>
        /// <param name="templateFile">模版文件名(包含路径后缀)  例:"模板文件名.xls"</param>
        /// <param name="rowIndex">从第几行开始创建数据行,第一行为0</param>
        /// <param name="mergeColumns">值相同时,可合并的前几列 最多支持2列 1=只合并第一列,2=判断前2列</param>
        /// <param name="isConver">是否覆盖数据,=false,将把原数据下移。=true,将覆盖插入行后面的数据</param>
        /// <param name="isTotal">是否带小计/合计项</param>
        /// <param name="addAllTotal">是否添加总计项</param>
        /// <returns>是否导出成功</returns>
        public static bool Export2Template2(DataTable source, string[] cellKeys, string strFileName, string templateFile, int rowIndex, int mergeColumns, bool isConver, bool isTotal, bool addAllTotal)
        {
            bool bn = false;
            int cellCount = cellKeys.Length; //总列数,第一列为0
            // IWorkbook workbook = null;
            HSSFWorkbook workbook = null;
            string temp0 = "", temp1 = "";
            int start0 = 0, start1 = 0;  // 记录1,2列值相同的开始序号
            int end0 = 0, end1 = 0;// 记录1,2列值相同的结束序号

            try
            {
                using (FileStream file = new FileStream(templateFile, FileMode.Open, FileAccess.Read))
                {
                    workbook = new HSSFWorkbook(file);
                }

                #region 定义四类数据的单元格样式
                // 内容数据格式 -- 数值
                ICellStyle styleNum = workbook.CreateCellStyle();
                styleNum.BorderBottom = BorderStyle.Thin;
                styleNum.BorderLeft = BorderStyle.Thin;
                styleNum.BorderRight = BorderStyle.Thin;
                styleNum.BorderTop = BorderStyle.Thin;
                // styleNum.VerticalAlignment = VerticalAlignment.Center;
                // styleNum.Alignment = HorizontalAlignment.Center;

                // 内容数据格式 -- 字符串(做居中处理)
                ICellStyle styleStr = workbook.CreateCellStyle();
                styleStr.BorderBottom = BorderStyle.Thin;
                styleStr.BorderLeft = BorderStyle.Thin;
                styleStr.BorderRight = BorderStyle.Thin;
                styleStr.BorderTop = BorderStyle.Thin;
                styleStr.VerticalAlignment = VerticalAlignment.Center;
                styleStr.Alignment = HorizontalAlignment.Center;

                // 汇总数据格式 -- 数值
                ICellStyle styleTotalNum = workbook.CreateCellStyle();
                styleTotalNum.BorderBottom = BorderStyle.Thin;
                styleTotalNum.BorderLeft = BorderStyle.Thin;
                styleTotalNum.BorderRight = BorderStyle.Thin;
                styleTotalNum.BorderTop = BorderStyle.Thin;
                styleTotalNum.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
                styleTotalNum.FillPattern = FillPattern.SolidForeground;
                styleTotalNum.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
                // 设置字体颜色
                HSSFFont ffont0 = (HSSFFont)workbook.CreateFont();
                // ffont0.FontHeight = 14 * 14;
                // ffont0.FontName = "宋体";
                ffont0.IsBold = true;
                //ffont0.Color = HSSFColor.Red.Index;
                styleTotalNum.SetFont(ffont0);

                // 汇总数据格式 -- 字符串(做居中处理)
                ICellStyle styleTotalStr = workbook.CreateCellStyle();
                styleTotalStr.BorderBottom = BorderStyle.Thin;
                styleTotalStr.BorderLeft = BorderStyle.Thin;
                styleTotalStr.BorderRight = BorderStyle.Thin;
                styleTotalStr.BorderTop = BorderStyle.Thin;
                styleTotalStr.VerticalAlignment = VerticalAlignment.Center;
                styleTotalStr.Alignment = HorizontalAlignment.Center;
                styleTotalStr.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
                styleTotalStr.FillPattern = FillPattern.SolidForeground;
                // 设置字体颜色
                HSSFFont ffont1 = (HSSFFont)workbook.CreateFont();
                // ffont1.FontHeight = 14 * 14;
                // ffont1.FontName = "宋体";
                ffont1.IsBold = true;
                //ffont.Color = HSSFColor.Red.Index;
                styleTotalStr.SetFont(ffont1);
                #endregion

                ISheet sheet = workbook.GetSheetAt(0);   // 打开第一个sheet页
                if (sheet != null && source != null && source.Rows.Count > 0)  // 模板内容为空,不做处理
                {
                    IRow row;
                    for (int i = 0, len = source.Rows.Count; i < len; i++)
                    {
                        if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false);   // 不覆盖,数据向下移

                        #region 第一行,写入数据后,对变量赋初值
                        if (i == 0) // 第一行,赋初值
                        {
                            row = sheet.CreateRow(rowIndex);
                            #region  创建列并插入数据
                            //创建列并插入数据
                            for (int index = 0; index < cellCount; index++)
                            {
                                ICell cell = row.CreateCell(index);

                                string strValue = !(source.Rows[i][cellKeys[index]] is DBNull) ? source.Rows[i][cellKeys[index]].ToString() : string.Empty;
                                // 其它列数据,数值进行汇总
                                switch (source.Columns[cellKeys[index]].DataType.ToString())
                                {
                                    case "System.Int16": //整型
                                    case "System.Int32":
                                    case "System.Int64":
                                    case "System.Byte":
                                        int intV = 0;
                                        int.TryParse(strValue, out intV);
                                        cell.CellStyle = styleNum;  // 设置格式
                                        cell.SetCellValue(intV);
                                        break;
                                    case "System.Decimal": //浮点型
                                    case "System.Double":
                                    case "System.Single":
                                        double doubV = 0;
                                        double.TryParse(strValue, out doubV);
                                        cell.CellStyle = styleNum;  // 设置格式
                                        cell.SetCellValue(doubV);
                                        break;
                                    default:
                                        cell.CellStyle = styleStr;  // 设置格式
                                        cell.SetCellValue(strValue);
                                        break;
                                }
                            }
                            #endregion

                            if (mergeColumns > 0)
                            {
                                temp0 = source.Rows[i][cellKeys[0]].ToString();  // 保存第1列值
                                start0 = rowIndex;
                                end0 = rowIndex;
                            }
                            if (mergeColumns > 1)
                            {
                                temp1 = source.Rows[i][cellKeys[1]].ToString();  // 保存第2列值                   
                                start1 = rowIndex;
                                end1 = rowIndex;
                            }

                            rowIndex++;
                            continue;
                        }
                        #endregion

                        // 不是第一行数据的处理
                        // 判断1列值变化没
                        string cellText0 = source.Rows[i][cellKeys[0]].ToString();
                        if (temp0 != cellText0) // 第1列值有变化
                        {
                            #region 第2列要合并
                            if (mergeColumns > 1)  // 第2列要合并
                            {
                                if (start1 != end1) // 开始行和结束行不相同,才进行合并
                                {
                                    CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列
                                    sheet.AddMergedRegion(region1);
                                }

                                #region 第2列加小计
                                if (isTotal) // 加小计
                                {
                                    if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false);   // 不覆盖,数据向下移

                                    IRow rowTotal1 = sheet.CreateRow(rowIndex);
                                    //创建列并插入数据
                                    #region 插入小计数据
                                    for (int index = 0; index < cellCount; index++)
                                    {
                                        object obj1;
                                        ICell newcell = rowTotal1.CreateCell(index);
                                        if (index == 0)   //第1列
                                        {
                                            newcell.CellStyle = styleTotalStr;
                                            newcell.SetCellValue(temp0);
                                            continue;
                                        }
                                        if (index == 1)   // 第2列
                                        {
                                            newcell.CellStyle = styleTotalStr;
                                            newcell.SetCellValue("小计"); 
                                            continue;
                                        }

                                        // 其它列数据,数值进行汇总
                                        switch (source.Columns[cellKeys[index]].DataType.ToString())
                                        {
                                            case "System.Int16": //整型
                                            case "System.Int32":
                                            case "System.Int64":
                                            case "System.Byte":
                                                obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1));
                                                int intV = 0;
                                                int.TryParse(obj1.ToString(), out intV);
                                                newcell.CellStyle = styleTotalNum;
                                                newcell.SetCellValue(intV);
                                                break;
                                            case "System.Decimal": //浮点型
                                            case "System.Double":
                                            case "System.Single":
                                                obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1));
                                                double doubV = 0;
                                                double.TryParse(obj1.ToString(), out doubV);
                                                newcell.CellStyle = styleTotalNum;
                                                newcell.SetCellValue(doubV);
                                                break;
                                            default:
                                                newcell.CellStyle = styleTotalStr;
                                                newcell.SetCellValue("");
                                                break;
                                        }
                                    }
                                    #endregion

                                    // 合并小计
                                    CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计
                                    sheet.AddMergedRegion(region0);

                                }
                                #endregion
                                temp1 = source.Rows[i][cellKeys[1]].ToString();
                                end0++;
                                rowIndex++;
                            }
                            #endregion

                            #region 第1列要合并
                            if (mergeColumns > 0)   // 第1列要合并
                            {
                                if (start0 != end0) // 开始行和结束行不相同,才进行合并
                                {
                                    CellRangeAddress region0 = new CellRangeAddress(start0, end0, 0, 0); // 合并第二列
                                    sheet.AddMergedRegion(region0);
                                }

                                #region 第1列加合计
                                if (isTotal) // 加合计
                                {
                                    if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false);   // 不覆盖,数据向下移

                                    IRow rowTotal0 = sheet.CreateRow(rowIndex);
                                    //创建列并插入数据
                                    #region 加合计列
                                    for (int index = 0; index < cellCount; index++)
                                    {
                                        object obj1;
                                        ICell newcell = rowTotal0.CreateCell(index);
                                        if (index == 0)
                                        {
                                            newcell.CellStyle = styleTotalStr;
                                            newcell.SetCellValue("合计");  //第1列
                                            continue;
                                        }
                                        if (index == 1)
                                        {
                                            newcell.CellStyle = styleTotalStr;
                                            newcell.SetCellValue("");  // 第2列
                                            continue;
                                        }

                                        switch (source.Columns[cellKeys[index]].DataType.ToString())
                                        {
                                            case "System.Int16": //整型
                                            case "System.Int32":
                                            case "System.Int64":
                                            case "System.Byte":
                                                obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ ", cellKeys[0], temp0));
                                                int intV = 0;
                                                int.TryParse(obj1.ToString(), out intV);
                                                newcell.CellStyle = styleTotalNum;
                                                newcell.SetCellValue(intV);
                                                break;
                                            case "System.Decimal": //浮点型
                                            case "System.Double":
                                            case "System.Single":
                                                obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ ", cellKeys[0], temp0));
                                                double doubV = 0;
                                                double.TryParse(obj1.ToString(), out doubV);
                                                newcell.CellStyle = styleTotalNum;
                                                newcell.SetCellValue(doubV);
                                                break;
                                            default:
                                                newcell.CellStyle = styleTotalStr;
                                                newcell.SetCellValue("");
                                                break;
                                        }
                                    }
                                    #endregion

                                    // 合并合计
                                    CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并合计
                                    sheet.AddMergedRegion(region0);

                                    end0++;
                                    rowIndex++;
                                }
                                #endregion
                                temp0 = cellText0;
                            }
                            #endregion

                            // 重新赋值
                            start0 = rowIndex;
                            end0 = rowIndex;
                            start1 = rowIndex;
                            end1 = rowIndex;
                        }
                        else  // 第1列值没有变化
                        {
                            end0++;
                            // 判断第2列是否有变化
                            string cellText1 = source.Rows[i][cellKeys[1]].ToString();
                            if (cellText1 != temp1)  // 第1列没变,第2列变化
                            {
                                #region 第2列要合并
                                if (mergeColumns > 1)  // 第2列要合并
                                {
                                    if (start1 != end1) // 开始行和结束行不相同,才进行合并
                                    {
                                        CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列
                                        sheet.AddMergedRegion(region1);
                                    }

                                    #region 第2列加小计
                                    if (isTotal) // 加小计
                                    {
                                        if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false);   // 不覆盖,数据向下移

                                        IRow rowTotal1 = sheet.CreateRow(rowIndex);
                                        //创建列并插入数据
                                        #region 插入小计数据
                                        for (int index = 0; index < cellCount; index++)
                                        {
                                            object obj1;
                                            ICell newcell = rowTotal1.CreateCell(index);
                                            if (index == 0)   //第1列
                                            {
                                                newcell.CellStyle = styleTotalStr;
                                                newcell.SetCellValue(temp0);
                                                continue;
                                            }
                                            if (index == 1)   // 第2列
                                            {
                                                newcell.CellStyle = styleTotalStr;
                                                newcell.SetCellValue("小计");
                                                continue;
                                            }

                                            // 其它列数据,数值进行汇总
                                            switch (source.Columns[cellKeys[index]].DataType.ToString())
                                            {
                                                case "System.Int16": //整型
                                                case "System.Int32":
                                                case "System.Int64":
                                                case "System.Byte":
                                                    obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1));
                                                    int intV = 0;
                                                    int.TryParse(obj1.ToString(), out intV);
                                                    newcell.CellStyle = styleTotalNum;
                                                    newcell.SetCellValue(intV);
                                                    break;
                                                case "System.Decimal": //浮点型
                                                case "System.Double":
                                                case "System.Single":
                                                    obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1));
                                                    double doubV = 0;
                                                    double.TryParse(obj1.ToString(), out doubV);
                                                    newcell.CellStyle = styleTotalNum;
                                                    newcell.SetCellValue(doubV);
                                                    break;
                                                default:
                                                    newcell.CellStyle = styleTotalStr;
                                                    newcell.SetCellValue("");
                                                    break;
                                            }
                                        }
                                        #endregion
                                        // 合并小计
                                        CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计
                                        sheet.AddMergedRegion(region0);

                                        end0++;
                                        rowIndex++;
                                    }
                                    temp1 = cellText1;  // 要合并,才进行重新赋值
                                    start1 = rowIndex;
                                    end1 = rowIndex;
                                    #endregion
                                }
                                #endregion
                            }
                            else  // 第1列值没变,第2列也没变
                                end1++;
                        }

                        // 插入当前数据
                        row = sheet.CreateRow(rowIndex);
                        #region  创建行并插入当前记录的数据
                        //创建行并插入当前记录的数据
                        for (int index = 0; index < cellCount; index++)
                        {
                            ICell cell = row.CreateCell(index);
string strValue = !(source.Rows[i][cellKeys[index]] is DBNull) ? source.Rows[i][cellKeys[index]].ToString() : string.Empty; // 取值 switch (source.Columns[cellKeys[index]].DataType.ToString()) { case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(strValue, out intV); cell.CellStyle = styleNum; cell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": case "System.Single": double doubV = 0; double.TryParse(strValue, out doubV); cell.CellStyle = styleNum; cell.SetCellValue(doubV); break; default: cell.CellStyle = styleStr; cell.SetCellValue(strValue); break; } } #endregion // 下移一行 rowIndex++; } // 最后一条记录的合计 #region 对第2列进行合并 if (mergeColumns > 1) // 对第2列合并 { if (start1 != end1) // 开始行和结束行不等,进行合并 { CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列 sheet.AddMergedRegion(region1); } #region 第2列加小计 if (isTotal) // 加小计 { if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移 IRow rowTotal1 = sheet.CreateRow(rowIndex); //创建列并插入数据 #region 插入小计数据 for (int index = 0; index < cellCount; index++) { object obj1; ICell newcell = rowTotal1.CreateCell(index); #region 列值处理 if (index == 0) //第1列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue(temp0); continue; } if (index == 1) // 第2列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue("小计"); continue; } // 其它列数据,数值进行汇总 switch (source.Columns[cellKeys[index]].DataType.ToString()) { case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1)); int intV = 0; int.TryParse(obj1.ToString(), out intV); newcell.CellStyle = styleTotalNum; newcell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": case "System.Single": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ and {2} = ‘{3}‘ ", cellKeys[0], temp0, cellKeys[1], temp1)); double doubV = 0; double.TryParse(obj1.ToString(), out doubV); newcell.CellStyle = styleTotalNum; newcell.SetCellValue(doubV); break; default: newcell.CellStyle = styleTotalStr; newcell.SetCellValue(""); break; } #endregion } #endregion // 合并小计 CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计 sheet.AddMergedRegion(region0); rowIndex++; end0++; } #endregion } #endregion #region 对第1列合并 if (mergeColumns > 0) // 对第1列合并 { if (start0 != end0) // 开始行和结束行不等,进行合并 { CellRangeAddress region1 = new CellRangeAddress(start0, end0, 0, 0); // 合并第二列 sheet.AddMergedRegion(region1); } #region 第1列加合计 if (isTotal) // 加合计 { if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移 IRow rowTotal0 = sheet.CreateRow(rowIndex); //创建列并插入数据 #region 插入合计数据 for (int index = 0; index < cellCount; index++) { object obj1; ICell newcell = rowTotal0.CreateCell(index); #region 列值处理 if (index == 0) //第1列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue("合计"); continue; } if (index == 1) // 第2列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue(""); continue; } // 其它列数据,数值进行汇总 switch (source.Columns[cellKeys[index]].DataType.ToString()) { case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ ", cellKeys[0], temp0)); int intV = 0; newcell.CellStyle = styleTotalNum; int.TryParse(obj1.ToString(), out intV); newcell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": case "System.Single": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = ‘{1}‘ ", cellKeys[0], temp0)); double doubV = 0; double.TryParse(obj1.ToString(), out doubV); newcell.CellStyle = styleTotalNum; newcell.SetCellValue(doubV); break; default: newcell.CellStyle = styleTotalStr; newcell.SetCellValue(""); break; } #endregion } #endregion // 合并合计 CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并合计 sheet.AddMergedRegion(region0); } rowIndex++; #endregion } #endregion #region 进行汇总 - 加总计 if (addAllTotal) // 加总计 { if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移 IRow rowTotal0 = sheet.CreateRow(rowIndex); //创建列并插入数据 #region 插入总计数据 for (int index = 0; index < cellCount; index++) { object obj1; ICell newcell = rowTotal0.CreateCell(index); #region 列值处理 if (index == 0) //第1列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue("总计"); continue; } if (index == 1) // 第2列 { newcell.CellStyle = styleTotalStr; newcell.SetCellValue(""); continue; } // 其它列数据,数值进行汇总 switch (source.Columns[cellKeys[index]].DataType.ToString()) { case "System.Int16": //整型 case "System.Int32": case "System.Int64": case "System.Byte": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), ""); int intV = 0; int.TryParse(obj1.ToString(), out intV); newcell.CellStyle = styleTotalNum; newcell.SetCellValue(intV); break; case "System.Decimal": //浮点型 case "System.Double": case "System.Single": obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), ""); double doubV = 0; double.TryParse(obj1.ToString(), out doubV); newcell.CellStyle = styleTotalNum; newcell.SetCellValue(doubV); break; default: newcell.CellStyle = styleTotalStr; newcell.SetCellValue(""); break; } #endregion } #endregion // 合并总计 CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并总计 sheet.AddMergedRegion(region0); } #endregion } return Save2Xls(strFileName, workbook); // 保存为xls文件 } catch (Exception ex) { // FileHelper.WriteLine(logfile, "处理数据异常:" + ex.Message); // msg = ex.Message; } return bn; }

 

  保存文件的代码:

        public static bool Save2Xls(string fileName, IWorkbook workbook)
        {
            bool bn = false;
            try
            {
                FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);

                MemoryStream ms = new MemoryStream();
                workbook.Write(ms);
                BinaryWriter w = new BinaryWriter(fs);
                w.Write(ms.ToArray());
                fs.Close();
                ms.Close();

                bn = true;
            }
            catch(Exception ex)
            {
                //FileHelper.WriteLine(logfile, "保存文件异常:" + ex.Message);
            }
            return bn;
        }

  

 

以上是关于NPOI实现两级分组合并功能的主要内容,如果未能解决你的问题,请参考以下文章

求一个c#winfrom 合并datagridview的效果通过npoi导出也是和dategridview合并效果一样的excel例子

npoi 合并单元值处理

Npoi--合并单元格

Jquery Datatables Grouping Plugin - 一种可扩展两级分组的方法?

NPOI导出Excel合并表头写入公式

NPOI合并单元格后边框显示不正确?