在工作开发中,客户经常要求数据库中数据导出到Excel表格。以前方法是引用office相关组件,如果客户没有安装office,功能就会遇到问题。
现在用Npoi导出Excel,导出表格是合并行列,如图:

导出的要求:合计列要进行合并,序号一致的要合并。最后一行要合并列。
因为相同序号数量不是固定的,要动态算合并的行数。
合并行列接口:XXX.AddMergedRegion(new CellRangeAddress(开始行, 最后一行, 开始列, 最后一列));
隐藏指定:sheet.SetColumnHidden(cellIndex, true);
引用组件:
NPOI.dll;
NPOI.OOXML.dll;
NPOI.OpenXml4Net.dll;
NPOI.OpenXmlFormats.dll;
ICSharpCode.SharpZipLib.dll;
代码如下:

           /// <summary>/// /// </summary>/// <param name="dtSource">数据源</param>/// <param name="strFileName">保存路径</param>/// <param name="dvXH">序号</param>public void Export(DataTable dtSource,string strFileName,DataView dvXH=null){//创建工作簿 office2007以上XSSFWorkbook workbook = new XSSFWorkbook();//为工作簿创建工作表并命名ISheet sheet = workbook.CreateSheet("商品表");ICellStyle dateStyle = workbook.CreateCellStyle();IDataFormat format = workbook.CreateDataFormat();dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");#region 表头及样式int cellIndex = 0;IRow headerRow = sheet.CreateRow(0);for (int i = 0; i < dtSource.Columns.Count; i++){#region MyRegionstring ColumnsName = dtSource.Columns[i].ToString();if (dtSource.Columns[i].ColumnName.EndsWith("XH")){ColumnsName = "序号";sheet.SetColumnWidth(cellIndex, 3000);//sheet.SetColumnHidden(cellIndex, true);隐藏指定列}else if (dtSource.Columns[i].ColumnName.EndsWith("GoogName")){ColumnsName = "商品名称";sheet.SetColumnWidth(cellIndex,10000);//设置列宽}else if (dtSource.Columns[i].ColumnName.EndsWith("Num")){ColumnsName = "数量";sheet.SetColumnWidth(cellIndex, 5000);}else if (dtSource.Columns[i].ColumnName.EndsWith("Summation")){ColumnsName = "合计(元)";sheet.SetColumnWidth(cellIndex, 5000);}#endregion//设置行高headerRow.HeightInPoints = 35; headerRow.CreateCell(cellIndex).SetCellValue(ColumnsName);ICellStyle headStyle = workbook.CreateCellStyle();headStyle.WrapText = true;IFont font = workbook.CreateFont();//字体大小font.FontHeightInPoints = 12;font.Boldweight = 360;headStyle.SetFont(font);headerRow.GetCell(cellIndex).CellStyle = headStyle;cellIndex++;}#endregionint rowIndex = 1;//行数一定要从1行开始int count = 1;int startRow = 1;DataView dvSource = dtSource.DefaultView;if (dvXH!=null){foreach (DataRowView drv in dvXH){//1-10.11-12,13-14,15-16int rowcout = 0;dvSource.RowFilter = "XH='" + drv["XH"] + "'";foreach (DataRowView row in dvSource){#region 填充内容IRow dataRow = sheet.CreateRow(rowIndex);//序号ICell newCel0 = dataRow.CreateCell(0);ICellStyle style0 = workbook.CreateCellStyle();style0.DataFormat = format.GetFormat("text");newCel0.SetCellValue(row["XH"].ToString());//标的名称ICell newCel2 = dataRow.CreateCell(1);ICellStyle style2 = workbook.CreateCellStyle();style2.DataFormat = format.GetFormat("text");newCel2.SetCellValue(row["GoogName"].ToString());//标的数量ICell newCel4 = dataRow.CreateCell(2);ICellStyle style4 = workbook.CreateCellStyle();style4.DataFormat = format.GetFormat("text");newCel4.SetCellValue(row["Num"].ToString());//合计(元)ICell newCel8 = dataRow.CreateCell(3);ICellStyle style8 = workbook.CreateCellStyle();style8.DataFormat = format.GetFormat("text");newCel8.SetCellValue(row["Summation"].ToString());#endregionrowIndex++;rowcout++;}if (count == 1){//合并行数sheet.AddMergedRegion(new CellRangeAddress(startRow, rowcout, 3, 3));startRow = startRow + rowcout;}else{sheet.AddMergedRegion(new CellRangeAddress(startRow, startRow + rowcout - 1, 3, 3));startRow = startRow + rowcout;}count++;}}else{#region MyRegionforeach (DataRowView row in dvSource){#region 填充内容IRow dataRow = sheet.CreateRow(rowIndex);//序号ICell newCel0 = dataRow.CreateCell(0);ICellStyle style0 = workbook.CreateCellStyle();style0.DataFormat = format.GetFormat("text");newCel0.SetCellValue(row["XH"].ToString());//商品名称ICell newCel1 = dataRow.CreateCell(1);ICellStyle style1 = workbook.CreateCellStyle();style1.DataFormat = format.GetFormat("text");newCel1.SetCellValue(row["GoogName"].ToString());//数量ICell newCel2 = dataRow.CreateCell(2);ICellStyle style2 = workbook.CreateCellStyle();style2.DataFormat = format.GetFormat("text");newCel2.SetCellValue(row["Num"].ToString());//合计(元)ICell newCel3 = dataRow.CreateCell(3);ICellStyle style3 = workbook.CreateCellStyle();style3.DataFormat = format.GetFormat("text");newCel3.SetCellValue(row["Summation"].ToString());#endregionrowIndex++;}#endregion}#region 拼接最后一行IFont fontLast = workbook.CreateFont();fontLast.FontHeightInPoints = 30;fontLast.Boldweight = 480;IRow dataRowLast = sheet.CreateRow(rowIndex);dataRowLast.HeightInPoints = 40;ICell newCelLast = dataRowLast.CreateCell(0);ICellStyle styleLast = workbook.CreateCellStyle();styleLast.DataFormat = format.GetFormat("text");styleLast.SetFont(fontLast);newCelLast.SetCellValue("制作人:张三");sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, 3));#endregionMemoryStream stream = new MemoryStream();workbook.Write(stream);var buf = stream.ToArray();using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)){fs.Write(buf, 0, buf.Length);fs.Flush();}}

实际运用中,涉及到数据,方法中有很多校验等操作,方法直观可读性不是太好,下面附上简单导出的方法:
实际上导出Excel,总结有几点:
1、引用相关组件
2、创建一个工作簿,创建工作表并命名;
3、设置表头及样式;
4、填充数据;
5、保存数据到指定位置;

        /// <summary>/// 简单导出数据/// </summary>/// <param name="dtSource">数据源</param>/// <param name="strFileName">保存路径</param>/// <param name="dvXH">序号</param>public void Export1(DataTable dtSource, string strFileName){//创建工作簿XSSFWorkbook workbook = new XSSFWorkbook();//为工作簿创建工作表并命名ISheet sheet = workbook.CreateSheet("商品表");IDataFormat format = workbook.CreateDataFormat();#region 表头及样式int cellIndex = 0;IRow headerRow = sheet.CreateRow(0);for (int i = 0; i < dtSource.Columns.Count; i++){//设置行高headerRow.HeightInPoints = 35;headerRow.CreateCell(cellIndex).SetCellValue(dtSource.Columns[i].ToString());ICellStyle headStyle = workbook.CreateCellStyle();headStyle.WrapText = true;IFont font = workbook.CreateFont();//字体大小font.FontHeightInPoints = 12;font.Boldweight = 360;headStyle.SetFont(font);headerRow.GetCell(cellIndex).CellStyle = headStyle;cellIndex++;}#endregion#region 数据填充int rowIndex = 1;//行数一定要从1行开始,因为上面已经创建了表头为0行;DataView dvSource = dtSource.DefaultView;foreach (DataRow row in dtSource.Rows){int ColumnIndex = 0;IRow dataRow = sheet.CreateRow(rowIndex);foreach (DataColumn column in dtSource.Columns){//序号ICell newCel0 = dataRow.CreateCell(ColumnIndex);ICellStyle style0 = workbook.CreateCellStyle();style0.DataFormat = format.GetFormat("text");//数据类型newCel0.SetCellValue(row[column.ColumnName].ToString());ColumnIndex++;}rowIndex++;}#endregion#region 保存到指定位置MemoryStream stream = new MemoryStream();workbook.Write(stream);var buf = stream.ToArray();using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)){fs.Write(buf, 0, buf.Length);fs.Flush();}#endregion}

c# Npoi导出Excel并合并行列相关推荐

  1. NPOI导出Excel示例

    摘要:使用开源程序NPOI导出Excel示例.NPOI首页地址:http://npoi.codeplex.com/,NPOI示例博客:http://tonyqus.sinaapp.com/. 示例编写 ...

  2. Winform中通过NPOI导出Excel时通过ICellStyle和IDataFormat格式化日期显示格式

    场景 Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载: https://blog.csdn.net/B ...

  3. Winforn中通过NPOI导出Excel时通过XSSFClientAnchor和XSSFPicture添加图片

    场景 Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载: https://blog.csdn.net/B ...

  4. NPOI 导出 excel 性能测试

    NPOI 导出 excel 性能测试 Intro 网上看到很多人说 NPOI 的性能不行,自己写了一个 NPOI 的扩展库,于是想尝试看看 NPOI 的性能究竟怎么样,道听途说始终不如自己动手一试. ...

  5. Npoi导出excel整理(附源码)

    前些日子做了一个简单的winform程序,需要导出的功能,刚开始省事直接使用微软的组件,但是导出之后发现效率极其低下,绝对像web那样使用npoi组件,因此简单的进行了整理,包括直接根据DataTab ...

  6. .NET NPOI导出Excel详解

    http://www.cnblogs.com/yinrq/p/5590970.html .NET NPOI导出Excel详解 NPOI,顾名思义,就是POI的.NET版本.那POI又是什么呢?POI是 ...

  7. NPOI导出excel(带图片)

    近期项目中用到Excel导出功能,之前都是用普通的office组件导出的方法,今天尝试用下NPOI,故作此文以备日后查阅. 1.NPOI官网http://npoi.codeplex.com/,下载最新 ...

  8. C#利用NPOI导出Excel

    C#利用NPOI导出Excel 第一篇文章 View Code 1 using System; 2 using System.Collections.Generic; 3 using System.L ...

  9. NPOI导出excel设置打印为A4纸张

    NPOI导出excel设置打印为A4纸张: Sheet sheet1 = hssfworkbook.CreateSheet("表(横版)");                 sh ...

最新文章

  1. Proximal Algorithms 3 Interpretation
  2. 『第12天』从ipc$ 连接失败讲起
  3. 在IIS上建立WAP网站的图文方法
  4. 知识图谱 (1)基本概念
  5. 注意区分啊~这里求的的事公共子串不是子序列。NOJ308-Substring
  6. cdn加载vue很慢_Vue.js 项目打包优化实践
  7. linux 网络 PING IP可以通,ping域名ping不通
  8. 开课吧Java课堂:什么是ArrayList类
  9. 使用数据分析工具的注意事项
  10. php+mysql_msqli简单实例
  11. Oracle P6培训系列:09定义计划编制视图
  12. 第二代支付系统专题之报文篇(二)大额支付报文完整版(含二代新增功能业务说明)
  13. MyBatis的优点和缺点
  14. 1041: 数列求和1
  15. 【历史上的今天】3 月 29 日:“机器人三定律”问世;电脑动画首次获得奥斯卡;Caldera Linux 沉浮史
  16. STM32串口屏应用
  17. C语言零基础,入门应该知道的事
  18. 阿里云配置二级域名与nginx代理踩坑
  19. 净水行业首家,安吉尔新水效国标检测能力获CNAS认可
  20. 前端和后端是如何实现交互的

热门文章

  1. 富爸爸系列全集图书清单
  2. 从数据库中读取经纬度,在google map 上进行标注(一)
  3. AI换脸-简单换脸、人脸对齐、关键点定位与画图
  4. EFCore:关于DDD中值对象(Owns)无法更新数值
  5. 基于python实现仿探迹和天眼
  6. 247 中心对称数 II
  7. google chrome
  8. Three.js 实现虎年春节3D创意页面
  9. halcon机器视觉实例1--表面划痕检测
  10. Java学习预科知识