NPOI操作EXCEL(四)——反射机制批量导出excel文件
前面我们已经实现了反射机制进行excel表格数据的解析,既然有上传就得有下载,我们再来写一个通用的导出方法,利用反射机制实现对系统所有数据列表的筛选结果导出excel功能。
我们来构想一下这样一个画面,管理员筛选出北京的所有员工数据,想导出成excel表格;管理员筛选出北京所有欠费的企业数据,想导出成excel表格;管理员想导出本月的工单报表到excel表格;管理员想导出近3月北京各岗位的运营报表到excel表格......
系统客服真是个神奇的职业,神马都想导出到excel表格!
那么对于我们的程序来说,该怎么做呢!由于每个导出功能对应的数据源都不一样,简单的方法很难做到,只能每个业务单写一个导出功能。
所以,我们再次沿用导入时使用的xml文件配置做桥梁,通过反射技术做具体实现的方法,做一个通用的EXCEL导出工具:传入DTO数据集合与xml规则集,返回excel文件流。
1.我们创建一个xml文件,里面存放所有需要导出功能涉及字段的规则集(博主项目涉及到的导出功能也就10来个列表,约涉及100多个字段(这儿未全部列出),故未分开成多个xml规则文件)
<?xml version="1.0" encoding="utf-8" ?>
<module>
<add ExportFieldName="姓名" PropertyName="Name" DataType="System.String"/>
<add ExportFieldName="手机号码" PropertyName="PhoneNumber" DataType="System.String"/>
<add ExportFieldName="性别" PropertyName="Sex" DataType="System.String"/>
<add ExportFieldName="民族" PropertyName="Nation" DataType="System.String"/>
<add ExportFieldName="出生日期" PropertyName="Birthday" DataType="System.String"/>
<add ExportFieldName="身份证号码" PropertyName="Cardid" DataType="System.String"/>
</module>
注:
1.导出的规则相对简单,所以我们创建一个简单的规则集类:
/// <summary>
/// 导出excel-中英文规则类
/// </summary>
public class ExportRegular
{
/// <summary>
/// 属性名称(英文)
/// </summary>
public string PropertyName { get; set; } /// <summary>
/// 数据类型
/// </summary>
public string DataType { get; set; } /// <summary>
/// 导出名称(中文)
/// </summary>
public string ExportFieldName { get; set; }
}
2.然后是解析XML规则集的方法
/// <summary>
/// 解析XML规则集文件
/// </summary>
/// <returns></returns>
public static List<ExportRegular> GetExportRegulars()
{
var result = new List<ExportRegular>(); var reader = new XmlTextReader(xmlpath);
var doc = new XmlDocument();
//从指定的XMLReader加载XML文档
doc.Load(reader); foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
var header = new ExportRegular(); if (node.Attributes["PropertyName"] != null)
header.PropertyName = node.Attributes["PropertyName"].Value;
if (node.Attributes["DataType"] != null)
header.DataType = node.Attributes["DataType"].Value;
if (node.Attributes["ExportFieldName"] != null)
header.ExportFieldName = node.Attributes["ExportFieldName"].Value; result.Add(header);
} return result;
}
2.我们的excel导出工具对外暴露两个静态方法:
public static MemoryStream CreateExcelStreamByDatas(List<object> objectDatas, KeyValuePair<string, string> excelHeader) public static MemoryStream CreateExcelStreamByDatas(List<KeyValuePair<List<object>, KeyValuePair<string, string>>> objectDatass)
一个是单sheet表单导出接口,一个是多表单导出接口(例:管理员导出东三省的员工数据,则导出excel含4个表单(1、东三省全部数据;2、辽宁省数据;3、吉林省数据;4、黑龙江省数据))
参数objectDatas是从库中筛选到的结果DTO数据集,excelHeader是一个键值对:key-表头名称,value-sheet表单名称
3.我们具体来看单表单方法的实现:
/// <summary>
/// 将数据转换成excel文件流输出 ->单表单导出接口
/// </summary>
/// <returns></returns>
public static MemoryStream CreateExcelStreamByDatas(List<object> objectDatas, KeyValuePair<string, string> excelHeader)
{
// 返回对象
var ms = new MemoryStream(); // excel工作簿
IWorkbook workbook = new HSSFWorkbook();
//导入数据到sheet表单
CreateExcelSheetByDatas(objectDatas, excelHeader.Key, excelHeader.Value, ref workbook); workbook.Write(ms);
ms.Flush();
ms.Position = ; return ms;
}
我们将具体功能逻辑抽象到了方法CreateExcelSheetByDatas中,
那么多表单的实现只需要修改第13行为:
foreach (KeyValuePair<List<object>, KeyValuePair<string, string>> keyValuePair in objectDatass)
{
//导入数据到sheet表单
CreateExcelSheetByDatas(keyValuePair.Key, keyValuePair.Value.Key, keyValuePair.Value.Value, ref workbook);
}
4.我们来实现最核心的方法CreateExcelSheetByDatas(博主还没来得及重构代码,所有逻辑都写在里面了,略长...)
/// <summary>
/// 根据传入数据新建sheet表单到指定workbook
/// </summary>
/// <param name="objectDatas"></param>
/// <param name="excelHeader"></param>
/// <param name="sheetName"></param>
/// <param name="regulars"></param>
/// <param name="workbook"></param>
private static void CreateExcelSheetByDatas(List<object> objectDatas, string excelHeader, string sheetName, ref IWorkbook workbook)
{
var regulars = GetExportRegulars(); // excel sheet表单
ISheet sheet = workbook.CreateSheet(sheetName);
// excel行数
int rows = ; #region 单元格 -表头格式 #region 表头字体 IFont fontTitle = workbook.CreateFont();
fontTitle.FontHeightInPoints = ;
fontTitle.Boldweight = (short)FontBoldWeight.BOLD; #endregion ICellStyle styleTitle = workbook.CreateCellStyle();
styleTitle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER;
styleTitle.SetFont(fontTitle);
styleTitle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER; #endregion #region 单元格 -表体格式 #region 表体字体 IFont fontMessage = workbook.CreateFont();
fontMessage.FontHeightInPoints = ; #endregion ICellStyle styleMessage = workbook.CreateCellStyle();
styleMessage.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER;
styleMessage.SetFont(fontMessage);
styleMessage.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER; #endregion // 创建表头并赋值
int firstRowCellCount = GetAttributeCount(objectDatas.First());
IRow headerRow = sheet.CreateRow(rows);
headerRow.HeightInPoints = ;
var headerCell = headerRow.CreateCell();
headerCell.SetCellValue(excelHeader); // 合并表头
var cellRangeAddress = new CellRangeAddress(rows, rows, , firstRowCellCount - );
sheet.AddMergedRegion(cellRangeAddress);
// 设置表头格式
headerCell.CellStyle = styleTitle; //生成表头
if (objectDatas.Any())
{
rows++;
// excel列数
int cells = -;
// 创建数据行
var firstRow = sheet.CreateRow(rows);
firstRow.HeightInPoints = ;
var objectData = objectDatas.FirstOrDefault();
foreach (System.Reflection.PropertyInfo p in objectData.GetType().GetProperties())
{
cells++;
var regular = regulars.Find(t => t.PropertyName == p.Name);
if (regular == null)
{
throw new Exception("导出excel时,出现未配置字段。表:" + objectData.GetType().Name + ",字段:" + p.Name);
}
var firstRowCell = firstRow.CreateCell(cells);
firstRowCell.SetCellValue(regular.ExportFieldName);
sheet.SetColumnWidth(cells, regular.ExportFieldName.Length * * );
firstRowCell.CellStyle = styleMessage;
}
} // 反射object对象,遍历字段
foreach (var objectData in objectDatas)
{
rows++;
// excel列数
int cells = -;
// 创建数据行
var messageRow = sheet.CreateRow(rows);
messageRow.HeightInPoints = ;
foreach (System.Reflection.PropertyInfo p in objectData.GetType().GetProperties())
{
cells++;
var regular = regulars.Find(t => t.PropertyName == p.Name);
var messageCell = messageRow.CreateCell(cells);
var value = p.GetValue(objectData);
if (value == null)
{
messageCell.SetCellValue("");
}
else
{
switch (regular.DataType)
{
case "datetime":
if (Convert.ToDateTime(value) == DateTime.MinValue)
{
messageCell.SetCellValue("");
}
else
{
messageCell.SetCellValue(
Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss"));
}
break;
case "int":
messageCell.SetCellValue(Convert.ToInt32(value));
break;
case "double":
messageCell.SetCellValue(Convert.ToDouble(value));
break;
case "bool":
var setValue = "是";
if (!(bool)value)
{
setValue = "否";
}
messageCell.SetCellValue(setValue);
break;
default:
messageCell.SetCellValue(value.ToString());
break;
}
}
messageCell.CellStyle = styleMessage;
}
}
}
注:
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的导入,会在下一篇博文贴出具体实现的代码,敬请期待~~~
原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~
NPOI操作EXCEL(四)——反射机制批量导出excel文件的更多相关文章
- NPOI 操作数据库中数据的导入导出(Excel.xls文件) 和null数据的处理。
App.config: <?xml version="1.0" encoding="utf-8" ?> <configuration> ...
- vue将指定区域的表格数据或element-ui中el-table的数据单笔或多笔批量导出excel
公司在后台管理系统开发中用到了 vue+element-ui 组合的框架,但随着需求的越来越复杂,前端的工作难度也呈几何倍数递增,工作量随之增大.这不,在项目中增加一个将列表数据导出为excel的需求 ...
- html table表格导出excel的方法 html5 table导出Excel HTML用JS导出Excel的五种方法 html中table导出Excel 前端开发 将table内容导出到excel HTML table导出到Excel中的解决办法 js实现table导出Excel,保留table样式
先上代码 <script type="text/javascript" language="javascript"> var idTmr; ...
- Excel实用技巧-如何批量提取excel工作表名称
Excel实用技巧-如何批量提取excel工作表名称 1. 打开Excel文件,点击“公式”栏,进而点击“定义管理器” 2. 在弹出的对话框中,点击新增按钮, 名称:“sheet”,引用位置:“=RE ...
- NPOI、MyXls、Aspose.Cells 导入导出Excel(转)
Excel导入及导出问题产生: 从接触.net到现在一直在维护一个DataTable导s出到Excel的类,时不时还会维护一个导入类.以下是时不时就会出现的问题: 导出问题: 如果是asp.net,你 ...
- 利用java反射机制实现读取excel表格中的数据
如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来. 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List<User>.Lis ...
- .net使用NPOI的XSSFWorkbook进行web开发中导出Excel
之前也使用过NPOI导出excel,这次是因为在导出的excel里新增了几个列,正好超出了255的限制,所以又要改了. 今天主要出了4个问题: 1. Invalid column index (256 ...
- JAVA POI XSSFWorkbook导出扩展名为xlsx的Excel,附带weblogic 项目导出Excel文件错误的解决方案
现在很多系统都有导出excel的功能,总结一下自己之前写的,希望能帮到其他人,这里我用的是XSSFWorkbook,我们项目在winsang 用的Tomcat,LInux上用的weblogic服务器, ...
- MVC 导出Excel 的其中一方法(View导出excel)
场景:mvc下导出excel 思路:使用View导出excel 步骤: 1.导出标签添加事件 $("#export_A").click(function(){ //省略代码.... ...
随机推荐
- 不懂CSS也能定制博客界面!
之前没想过定制博客界面,毕竟CSS,HTML什么的都不懂,不过看了这篇文章分分钟搞定: [详细图解]一步一步教你自定义博客园(cnblog)界面 我是基于模板BlueSky做了些改动,先看修改前后的效 ...
- svn+teamcity+YouTrack+Upsource搭建—写给明天工作室的小伙伴
首先解释下概念: SVN:Subversion的简称,版本控制系统.采用集中式管理(本地只保留服务器仓储的副本,想要把代码交到服务器或者看提交记录.差异对比就必须得有网络连接) Teamcity:可持 ...
- 快来熟练使用 Mac 编程
熟练使用工具,可以提高一个人的做事效率- 1. iTerm2快捷键使用 ⌘ + d: 垂直分屏,⌘ + shift + d: 水平分屏. ⌘ + ]和⌘ + [在最近使用的分屏直接切换.而⌘ + op ...
- 分布式文件系统 - FastDFS 在 CentOS 下配置安装部署
少啰嗦,直接装 看过上一篇分布式文件系统 - FastDFS 简单了解一下的朋友应该知道,本次安装是使用目前余庆老师开源的最新 V5.05 版本,是余庆老师放在 Github 上的,和目前你能在网络上 ...
- 9.6 MongoDB一
目录:ASP.NET MVC企业级实战目录 9.6.1 MongoDB简介 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统 ...
- 客户关系管理系统-CRM源码
QQ:2112326142 邮箱:jxsupport@qq.com 本公司开发的CRM源代码系统一份,附源代码,本公司产品唯一销售客服QQ号:2112326142 请联系此QQ号,以免给您的工作 ...
- 国外远控软件DarkComet-RAT
下载地址:[点此下载] 使用步骤: 注册noip.org账号创建主机地址. 安装并配置DUC. 配置监听端口 配置NO-IP Updater 然后点击Update ,配置成功则会提示Success. ...
- iOS之数字的格式化
//通过NSNumberFormatter,同样可以设置NSNumber输出的格式.例如如下代码: NSNumberFormatter *formatter = [[NSNumberFormatter ...
- 解决NSTimer存在的内存泄漏的问题
创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...
- @property中的copy.strong.weak总结
1.NSString类型的属性为什么用copy NSString类型的属性可以用strong修饰,但会造成一些问题,请看下面代码 #import "ViewController.h" ...