HTML5技术

NPOI操作EXCEL(四)——反射机制批量导出excel文件 - 彩色铅笔

字号+ 作者:H5之家 来源:博客园 2015-10-21 08:22 我要评论( )

前面我们已经实现了反射机制进行excel表格数据的解析,既然有上传就得有下载,我们再来写一个通用的导出方法,利用反射机制实现对系统所有数据列表的筛选结果导出excel功能。 我们来构想一下这样一个画面,管理员筛选出北京的所有员工数据,想导出成excel表

前面我们已经实现了反射机制进行excel表格数据的解析,既然有上传就得有下载,我们再来写一个通用的导出方法,利用反射机制实现对系统所有数据列表的筛选结果导出excel功能。

 

我们来构想一下这样一个画面,管理员筛选出北京的所有员工数据,想导出成excel表格;管理员筛选出北京所有欠费的企业数据,想导出成excel表格;管理员想导出本月的工单报表到excel表格;管理员想导出近3月北京各岗位的运营报表到excel表格......

系统客服真是个神奇的职业,神马都想导出到excel表格!

那么对于我们的程序来说,该怎么做呢!由于每个导出功能对应的数据源都不一样,简单的方法很难做到,只能每个业务单写一个导出功能。

 

所以,我们再次沿用导入时使用的xml文件配置做桥梁,通过反射技术做具体实现的方法,做一个通用的EXCEL导出工具:传入DTO数据集合与xml规则集,返回excel文件流。

 

1.我们创建一个xml文件,里面存放所有需要导出功能涉及字段的规则集(博主项目涉及到的导出功能也就10来个列表,约涉及100多个字段(这儿未全部列出),故未分开成多个xml规则文件)

encoding=?> 2 <module> PropertyName=DataType=/> PropertyName=DataType=/> PropertyName=DataType=/> PropertyName=DataType=/> PropertyName=DataType=/> PropertyName=DataType=/> 9 </module>

注:

1.导出的规则相对简单,所以我们创建一个简单的规则集类:

导出excel-中英文规则类 ExportRegular 5 { 属性名称(英文) PropertyName { get; set; } 数据类型 DataType { get; set; } 导出名称(中文) ExportFieldName { get; set; } 20 }

2.然后是解析XML规则集的方法

解析XML规则集文件 List<ExportRegular> GetExportRegulars() 6 { 7 var result = new List<ExportRegular>(); reader = new XmlTextReader(xmlpath); 10 var doc = new XmlDocument(); doc.Load(reader); (XmlNode node in doc.DocumentElement.ChildNodes) 15 { 16 var header = new ExportRegular(); (node.Attributes[] != null) ].Value; ] != null) ].Value; ] != null) ].Value; 24 25 result.Add(header); 26 } result; 29 }

2.我们的excel导出工具对外暴露两个静态方法:

MemoryStream CreateExcelStreamByDatas(List<object> objectDatas, KeyValuePair<string, string> excelHeader) MemoryStream CreateExcelStreamByDatas(List<KeyValuePair<List<object>, KeyValuePair<string, string>>> objectDatass)

一个是单sheet表单导出接口,一个是多表单导出接口(例:管理员导出东三省的员工数据,则导出excel含4个表单(1、东三省全部数据;2、辽宁省数据;3、吉林省数据;4、黑龙江省数据))

参数objectDatas是从库中筛选到的结果DTO数据集,excelHeader是一个键值对:key-表头名称,value-sheet表单名称

3.我们具体来看单表单方法的实现:

将数据转换成excel文件流输出 ->单表单导出接口 MemoryStream CreateExcelStreamByDatas(List<object> objectDatas, KeyValuePair<string, string> excelHeader) 6 { ms = new MemoryStream(); IWorkbook workbook = new HSSFWorkbook(); CreateExcelSheetByDatas(objectDatas, excelHeader.Key, excelHeader.Value, ref workbook); 14 15 workbook.Write(ms); 16 ms.Flush(); 17 ms.Position = 0; ms; 20 }

我们将具体功能逻辑抽象到了方法CreateExcelSheetByDatas中,

那么多表单的实现只需要修改第13行为:

1 foreach (KeyValuePair<List<object>, KeyValuePair<string, string>> keyValuePair in objectDatass) 2 { CreateExcelSheetByDatas(keyValuePair.Key, keyValuePair.Value.Key, keyValuePair.Value.Value, ref workbook); 5 }

 4.我们来实现最核心的方法CreateExcelSheetByDatas(博主还没来得及重构代码,所有逻辑都写在里面了,略长...)

根据传入数据新建sheet表单到指定workbook CreateExcelSheetByDatas(List<object> objectDatas, string excelHeader, string sheetName, ref IWorkbook workbook) 10 { 11 var regulars = GetExportRegulars(); ISheet sheet = workbook.CreateSheet(sheetName); rows = 0; 单元格 -表头格式 表头字体 21 22 IFont fontTitle = workbook.CreateFont(); 23 fontTitle.FontHeightInPoints = 12; 24 fontTitle.Boldweight = (short)FontBoldWeight.BOLD; ICellStyle styleTitle = workbook.CreateCellStyle(); 29 styleTitle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER; 30 styleTitle.SetFont(fontTitle); 31 styleTitle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER; 单元格 -表体格式 表体字体 38 39 IFont fontMessage = workbook.CreateFont(); 40 fontMessage.FontHeightInPoints = 10; ICellStyle styleMessage = workbook.CreateCellStyle(); 45 styleMessage.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER; 46 styleMessage.SetFont(fontMessage); 47 styleMessage.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER; firstRowCellCount = GetAttributeCount(objectDatas.First()); 53 IRow headerRow = sheet.CreateRow(rows); 54 headerRow.HeightInPoints = 40; 55 var headerCell = headerRow.CreateCell(0); 56 headerCell.SetCellValue(excelHeader); cellRangeAddress = new CellRangeAddress(rows, rows, 0, firstRowCellCount - 1); 60 sheet.AddMergedRegion(cellRangeAddress); headerCell.CellStyle = styleTitle; (objectDatas.Any()) 67 { 68 rows++; cells = -1; firstRow = sheet.CreateRow(rows); 73 firstRow.HeightInPoints = 16; 74 var objectData = objectDatas.FirstOrDefault(); 75 foreach (System.Reflection.PropertyInfo p in objectData.GetType().GetProperties()) 76 { 77 cells++; 78 var regular = regulars.Find(t => t.PropertyName == p.Name); 79 if (regular == null) 80 { Exception(+ objectData.GetType().Name + + p.Name); 82 } 83 var firstRowCell = firstRow.CreateCell(cells); 84 firstRowCell.SetCellValue(regular.ExportFieldName); 85 sheet.SetColumnWidth(cells, regular.ExportFieldName.Length * 256 * 4); 86 firstRowCell.CellStyle = styleMessage; 87 } 88 } (var objectData in objectDatas) 92 { 93 rows++; cells = -1; messageRow = sheet.CreateRow(rows); 98 messageRow.HeightInPoints = 16; 99 foreach (System.Reflection.PropertyInfo p in objectData.GetType().GetProperties()) 100 { 101 cells++; 102 var regular = regulars.Find(t => t.PropertyName == p.Name); 103 var messageCell = messageRow.CreateCell(cells); 104 var value = p.GetValue(objectData); 105 if (value == null) 106 { 107 messageCell.SetCellValue(""); 108 } { 111 switch (regular.DataType) 112 { : 114 if (Convert.ToDateTime(value) == DateTime.MinValue) 115 { 116 messageCell.SetCellValue(""); 117 } { 120 messageCell.SetCellValue( )); 122 } 123 break; : 125 messageCell.SetCellValue(Convert.ToInt32(value)); 126 break; : 128 messageCell.SetCellValue(Convert.ToDouble(value)); 129 break; : ; 132 if (!(bool)value) 133 { ; 135 } 136 messageCell.SetCellValue(setValue); 137 break; 138 default: 139 messageCell.SetCellValue(value.ToString()); 140 break; 141 } 142 } 143 messageCell.CellStyle = styleMessage; 144 } 145 } 146 }

注:

1.第18到62行均是对表体、表头字体格式的指定,并创建合并表头名称

2.第66行到88行是在遍历DTO属性,按规则集取出对应中文名称创建表头字段

此处特别说明:博主把所有导出DTO的所有属性字段都是做的简单类型字段,方便做反射。

3.第52行GetAttributeCount方法,是获取DTO对象所有属性个数

4.第91行到145行是按规则集规则将DTO中对应数据写进excel单元格

 

至此,我们就实现了将DTO集合按规则集导出到excel表格的方法。

我们只需要在各个导出服务中,先查库获取到需要的数据集合,再Map到DTO集合中,作为参数调用EXCEL导出方法即可返回需要的excel文件流。

 

到这儿,NPOI操作简单模板excel进行导入导出的相关代码就贴完了。如有什么地方写的不对或不好,欢迎指出,一定虚心请教~~~

上一篇博文说到的那些反人类的excel的导入,会在下一篇博文贴出具体实现的代码,敬请期待~~~

 

原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Linux系统(一)文件系统、压缩、打包操作总结 - 张龙豪

    Linux系统(一)文件系统、压缩、打包操作总结 - 张龙豪

    2017-02-23 16:00

  • 详解Google Chrome浏览器(操作篇) - Alan_beijing

    详解Google Chrome浏览器(操作篇) - Alan_beijing

    2017-02-13 15:01

  • SVG基础以及使用Javascript DOM操作SVG - 管的宽

    SVG基础以及使用Javascript DOM操作SVG - 管的宽

    2017-01-14 11:00

  • 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6) - 三生石上

    【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6) - 三生石上

    2016-12-23 17:00

网友点评