欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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#开发教程之利用特性自定义数据导出到excel,希望对大家有所帮助