C#通过反射导出任意Model实体类中的数据到Excel
需求:通过ComboBox选择要导出的数据表,然后导出成Excel。
程序中因偷懒已经使用EF,Spring.Net。
配置好spring.net,在程序中手动创建容器
IApplicationContext ctx = ContextRegistry.GetContext();
根据选择的不同表创建不同对象,通过反射根据拿到类和类中的属性,将数据从数据库中取出到DataTable。平时因用List<T>比较多,Dal中没有直接将数据库数据转成DataTable的方法,这里将List<T>再转成的DataTable,这里写的有些繁琐。
var table = ctx.GetObject(tableName + "Service"); var bll = table as IS_ACTIONINFOService; var datas = bll.GetEntitiesAsNoTracking().ToList(); if (datas.Count > 0) { var properties = datas[0].GetType().GetProperties(); foreach (var property in properties) { dt.Columns.Add(property.Name, property.PropertyType); } for (int i = 0; i < datas.Count; i++) { ArrayList tempList = new ArrayList(); foreach (PropertyInfo property in properties) { object obj = property.GetValue(datas[i], null); tempList.Add(obj); } object[] array = tempList.ToArray(); dt.LoadDataRow(array, true); } }
导出使用的NOPI将DataTable批量写入Excel,比用List<T>写入要快
COMMON.ExcelHelper.DataTable2Excel(dt, sheetName, fileName, headerRows, ref errorMsg)
目前已经可以将部分数据库中的数据表导出到Excel了,但是出现了Bug。
DataSet不支持System.Nullable<>,查找原因是因为DataSet不支持泛型。
在通过EF生成实体类的时候,会将数据库中非varchar的可空字段生成可空值类型的属性。
这些类型保存的是Nullable<>的泛型类型。
这里需要提取出其中的值类型。
Type currentType = property.PropertyType; if (currentType.IsGenericType && currentType.GetGenericTypeDefinition() == typeof(Nullable<>)) { currentType = currentType.GetGenericArguments()[0]; } dt.Columns.Add(property.Name, currentType);
修改后目前程序可以跑通了,不知道后面会不会出现新的bug。
每天写bug,改bug,生命不息,bug不止。