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);<br>
     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实现两级分组合并功能(示例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法

    今天在做项目中,遇到使用代码生成具有一定样式的Excel,找了很多资料,最后终于解决了,Excel中格式的设置,以及单元格的合并等等.下面就介绍下,使用NPOI类库操作Excel的方法. 1.首先我们先在内存中生成一个Excel文件,代码如下:   HSSFWorkbook book = new HSSFWorkbook();        ISheet sheet = book.CreateSheet("Sheet1"); 2.然后在新创建的sheet里面,创建我们的行和列,代码如下

  • NPOI实现两级分组合并功能(示例讲解)

    NPOI版本:2.2.1.0 最近公司有这样的需求: 统计每个部门下面,多个费用使用情况.部门存在多级,但统计时,只需统计到2级,2级以下的,归到第2级的部门下.并且要求,第2级部门有个小计,第1级部门需要有个合计.最后,还需提供总计. 本来对NPOI研究的还不够深入的,以前都是直接通过别人提供的代码来实现对DataTable中的数据进行全部导出,但里面不带合并,及合计功能,不满足当前需求.不得已,只有好好地研究一下了.还好,最终实现了要求. 在此,也感谢其他提供相关资料的人员,让我实现了此功能

  • JS和C#实现的两个正则替换功能示例分析

    本文实例讲述了JS和C#实现的两个正则替换功能.分享给大家供大家参考,具体如下: 应用实例1: 待处理字符串:str="display=test name=mu display=temp" 要求:把display=后的值都改成localhost JS处理方法: str.replace(/display=\w*/g,"display=localhost"); C#处理方法: Regex reg=new Regex(@"display=\w*");

  • Python实现两款计算器功能示例

    本文实例为大家分享了Python实现计算器功能示例代码,供大家参考,具体内容如下 1.简单计算器 #计算一个表达式的时候,首先肯定是先算括号里面的,再算乘除法,后算加减法 import re # 1.去括号 def remove_kuohao(expression): ''' 这是一个去除括号的函数 :param expression: 传进来的表达式 :return: 计算后的结果 ''' while True: ret = re.search(r'\([^(]*?\)',expression

  • AngularJS指令与指令之间的交互功能示例

    本文实例讲述了AngularJS指令与指令之间的交互功能.分享给大家供大家参考,具体如下: 前面一篇文章<AngularJS指令与控制器之间的交互功能示例>我们了解了指令与控制器之间的交互,接下来看看指令与指令之间是如何进行交互的. 1.首先来了解一下什么是独立scope 为了更好的理解独立scope,我们来看一段代码: <div ng-controller="myController1"> <hello></hello> <hel

  • jsp实现上一页下一页翻页功能(示例代码)

    前段时间一直忙于期末考试和找实习,好久没写博客了. 这段时间做了个小项目,包含了翻页和富文本编辑器Ueditor的两个知识点,Ueditor玩的还不是很深,打算玩深后再写篇博客. 要实现翻页功能,只需要设置一个pageIndex即可,然后每次加载页面时通过pageIndex去加载数据就行. 那么我们可以设置一个隐藏的input框,用于传递pageIndex给下个页面. 当我们点击上一页的时候,通过js方法改变pageIndex的值,再提交表单即可 二话不多说,看代码,代码里面写的还算比较清楚.

  • Android 获取随机验证码功能示例

    验证码功能在各大网站都能用到,下面小编通过实例代码给大家分享Android 获取随机验证码功能,具体代码如下所示: package cn.hk.image; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; impo

  • JavaWeb 中Cookie实现记住密码的功能示例

    本文主要内容: •1.什么是Cookie •2.Cookie带来的好处 •3.Cookie的主要方法 一.什么是Cookie cookie是一种WEB服务器通过浏览器在访问者的硬盘上存储信息的手段.Cookie的目的就是为用户带来方便,为网站带来增值.虽然有着许多误传,事实上Cookie并不会造成严重的安全威胁.Cookie永远不会以任何方式执行,因此也不会带来病毒或攻击你的系统.另外,由于浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为

  • Python实现翻转数组功能示例

    本文实例讲述了Python实现翻转数组功能.分享给大家供大家参考,具体如下: 题目描述 给定一个长度为n的整数数组a,元素均不相同,问数组是否存在这样一个片段,只将该片段翻转就可以使整个数组升序排列.其中数组片段[l,r]表示序列a[l], a[l+1], ..., a[r].原始数组为 a[1], a[2], ..., a[l-2], a[l-1], a[l], a[l+1], ..., a[r-1], a[r], a[r+1], a[r+2], ..., a[n-1], a[n], 将片段[

  • Angular实现下拉框模糊查询功能示例

    本文实例讲述了Angular实现下拉框模糊查询功能.分享给大家供大家参考,具体如下: 前两天研究了一下angularjs,不得不说angularjs的mvc思想还是很强大的.对应偏重于数据处理的项目还是非常有优势的. 写了个搜索下拉框的demo,注释在里边都写了,就不再这罗嗦了. 1. 普通方式实现 <!DOCTYPE html> <html> <head lang="zh_CN"> <meta charset="utf-8"

  • Angular实现的内置过滤器orderBy排序与模糊查询功能示例

    本文实例讲述了Angular实现的内置过滤器orderBy排序与模糊查询功能.分享给大家供大家参考,具体如下: 先来看看运行效果: 具体代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>www.jb51.net Angular模糊查询.排序</title> <style> *{ ma

随机推荐