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实现两级分组合并功能(示例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
Vue初始化中的选项合并之initInternalComponent详解
这篇文章主要介绍了Vue初始化中的选项合并之initInternalComponent的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-11- 这篇文章主要介绍了JavaScript数组合并案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-16
- 这篇文章主要为大家详细介绍了C#合并及拆分PDF文件的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了ES2020系列之空值合并运算符 '??',文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-22
- 这篇文章主要为大家详细介绍了C#合并多种格式文件为PDF的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了C#实现简单合并word文档的方法,涉及C#针对word文档的读取、插入、保存等技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 今天小编就为大家分享一篇Python-numpy实现灰度图像的分块和合并方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
- 今天小编就为大家分享一篇TensorFlow2.0:张量的合并与分割实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
- 这篇文章主要介绍了R语言实现按照某一列分组求均值的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
- PHP是现在很多用户使用的软件,用途很多并且有很大的作用。今天文章就给大家介绍个实例:PHP怎么实现根据数组的值进行分组,感兴趣的赶紧来看看。 本文实例讲述了PHP实...2017-07-06
- 这篇文章主要介绍了pandas 实现某一列分组,其他列合并成list的案例。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-26
- 这篇文章主要介绍了C#基于NPOI生成具有精确列宽行高的Excel文件的方法,是C#项目开发中非常实用的技巧,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了Java在Excel中创建多级分组、折叠或展开分组的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-28
- 这篇文章主要介绍了postgresql数据合并,多条数据合并成1条的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
- C# 合并GriewView相同列的小例子,需要的朋友可以参考一下...2020-06-25
Queryable.Union 方法实现json格式的字符串合并的具体实例
这篇文章介绍了Queryable.Union 方法实现json格式的字符串合并的具体实例,有需要的朋友可以参考一下...2021-09-22- 这篇文章主要介绍了使用itextpdf解决PDF合并的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-07
- 网站页面的响应速度与用户体验息息相关,直接影响到用户是否愿意继续访问你的网站,所以这篇文章主要给大家介绍了关于Vue项目打包、合并及压缩优化网页响应速度的相关资料,需要的朋友可以参考下...2021-07-07
- C#操作Excel的方法有很多种,本文介绍了C#通过NPOI操作Excel,具有一定的参考价值,有兴趣的可以了解一下。...2020-06-25
ASP.NET中GridView和Repeater重复数据如何合并
这篇文章主要介绍了ASP.NET中GridView和Repeater重复数据合并的方法,感兴趣的小伙伴们可以参考一下...2021-09-22