C#开发教程之利用特性自定义数据导出到Excel
程序员文章站
2023-08-29 21:37:34
网上c#导出excel的方法有很多。但用来用去感觉不够自动化。于是花了点时间,利用特性做了个比较通用的导出方法。只需要根据实体类,自动导出想要的数据
1.在nuget...
网上c#导出excel的方法有很多。但用来用去感觉不够自动化。于是花了点时间,利用特性做了个比较通用的导出方法。只需要根据实体类,自动导出想要的数据
1.在nuget上安装aspose.cells或者用微软自带类库也可以
2.需要导出的数据的实例类:
using system.componentmodel; using system.reflection; using system.runtime.serialization; public class orderreport { [displayname("订单编号")] public string orderno { get; set; } [ignoredatamember] public datetime ordertime { get; set; } [displayname("订单时间")] public string ordertime_fomart { get { return ordertime.toshortdatestring(); } } [displayname("商品编码")] public string itemcode { get; set; } [displayname("商品名称")] public string itemname { get; set; } }
定义实体中加上 [displayname("订单编号")]用来导出到excel生成列名。不需在导出一一对应写列名。[ignoredatamember]属性是用来导出是忽略掉不用导出 。
关于特性的介绍详细请参考msdn。
3.实现导出方法:
/// <summary> /// 导出类 /// </summary> public class exporthandle { /// <summary> /// 挂起订单报表导出 /// </summary> public static void execexportorderreport() { var orderreportlist = new list<orderreport>() { new orderreport() { orderno= "xd00001",ordertime=datetime.now, itemcode="g001" ,itemname="辣条"} , new orderreport() { orderno= "xd00002", ordertime=datetime.now,itemcode="g002" ,itemname="茶蛋"} , new orderreport() { orderno= "xd00003", ordertime=datetime.now,itemcode="g003" ,itemname="切糕"} , new orderreport() { orderno= "xd00004", ordertime=datetime.now,itemcode="g004" ,itemname="大虾"} , new orderreport() { orderno= "xd00005", ordertime=datetime.now,itemcode="g005" ,itemname="帝王蟹"} }; string path = "orderreport.xlsx"; console.writeline("开始执行导出"); outdatatoexcel(orderreportlist, "订单报表", path); console.writeline("导出完成:位置"+path); } /// <summary> /// 导出方法 /// </summary> /// <typeparam name="t"></typeparam> /// <param name="list">导出的数据list</param> /// <param name="title">数据类容标题</param> /// <param name="path">导出excel存放路径</param> public static void outdatatoexcel<t>(list<t> list, string title, string path) { workbook workbook = new workbook(); //工作簿 worksheet sheet = workbook.worksheets[0]; //工作表 sheet.isgridlinesvisible = false;//去掉初始单元线 cells cells = sheet.cells;//单元格 //为标题设置样式 style styletitle = workbook.createstyle();//新增样式 styletitle.horizontalalignment = textalignmenttype.center;//文字居中 styletitle.font.name = "微软雅黑";//文字字体 styletitle.font.size = 18;//文字大小 styletitle.font.isbold = true;//粗体 //样式1 标题下方的日期 style style1 = workbook.createstyle();//新增样式 style1.horizontalalignment = textalignmenttype.center;//文字居中 style1.font.name = "微软雅黑";//文字字体 style1.font.size = 12;//文字大小 //样式2 列名 style style2 = workbook.createstyle();//新增样式 style2.horizontalalignment = textalignmenttype.center;//文字居中 style2.font.name = "微软雅黑";//文字字体 style2.font.size = 12;//文字大小 style2.font.isbold = true;//粗体 style2.borders[bordertype.leftborder].linestyle = cellbordertype.thin; style2.borders[bordertype.rightborder].linestyle = cellbordertype.thin; style2.borders[bordertype.topborder].linestyle = cellbordertype.thin; style2.borders[bordertype.bottomborder].linestyle = cellbordertype.thin; //样式3 数据的样式 style style3 = workbook.createstyle();//新增样式 style3.horizontalalignment = textalignmenttype.center;//文字居中 style3.font.name = "微软雅黑";//文字字体 style3.font.size = 10;//文字大小 style3.borders[bordertype.leftborder].linestyle = cellbordertype.thin; style3.borders[bordertype.rightborder].linestyle = cellbordertype.thin; style3.borders[bordertype.topborder].linestyle = cellbordertype.thin; style3.borders[bordertype.bottomborder].linestyle = cellbordertype.thin; if (list.count == 0) return; var t = list.first().gettype();//获取列表的类的属性 //通过反射筛选忽略掉[ignoredatamemberattribute]的字段 var properties = t.getproperties().where(x => x.getcustomattribute<ignoredatamemberattribute>() == null); int colnum = properties.count();//表格列数 int rownum = list.count;//表格行数 //生成行1 标题行 cells.merge(0, 0, 1, colnum);//合并单元格 cells[0, 0].putvalue(title);//填写内容 cells[0, 0].setstyle(styletitle); cells.setrowheight(0, 38);//行高 //生成行2 日期 cells.merge(1, 0, 1, colnum);//合并单元格 cells[1, 0].putvalue(datetime.now.toshortdatestring());//填写内容 cells[1, 0].setstyle(style1); cells.setrowheight(1, 20);//行高 //列名及数据行 int i = 0; foreach (var item in properties) { var itemtype = t.getproperty(item.name); var colname = itemtype.getcustomattribute<displaynameattribute>().displayname;//反射获取字段的displayname特性值 cells[2, i].putvalue(colname); cells[2, i].setstyle(style2); cells.setcolumnwidth(i, colname.length * 3);//设置列宽 int k = 0; foreach (var rowdata in list) { //反射遍历添加数据 object value = rowdata.gettype().getproperty(item.name).getvalue(rowdata, null); string ss = value == null ? "" : value.tostring(); cells[3 + k, i].putvalue(ss); cells[3 + k, i].setstyle(style3); cells.setrowheight(3 + k, 18);//设置行高 k++; } i++; } workbook.save(path);//生成excel } }
导出方法 outdatatoexcel<t>(list<t> list, enum en, string path)用了泛型参数,将任意的实体list自动导出。
var properties = t.getproperties().where(x => attributeaccessor.getattribute<ignoredatamemberattribute>(x) == null);
采用lamda表达式在传过来的实体属性中筛选出
不是ignoredatamemberattribute的属性字段
foreach (var item in properties){}遍历实体类的属性相当于datatable循环读取数据 object value = rowdata.gettype().getproperty(item.name).getvalue(rowdata, null); 通过属性名称获取属性值。 通过以上两个步骤,实现自动 }
4.导出结果:
总结,通过特性来实现通用的导出。只需要设置相关的类的字段和特性值即可自定义导出
以上所述是小编给大家介绍的c#开发教程之利用特性自定义数据导出到excel,希望对大家有所帮助
下一篇: C#环形缓冲区(队列)完全实现