记得第一篇文章就是.net core 通过NPOI 导入导出excel(csv),之前的那种方式由于我们需要自定表头,每次都要手动写表头非常麻烦。特别是非常多列表头的时候我们得崩溃,,不利于扩展。
所以之后就想着有没有试着获取属性的描述来设置表头,果然尝试成功,然后就方便多了。
首先我们来看之前的导出代码:
public static byte[] OutputExcel(List<T> entitys, string[] title) { IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet("sheet"); IRow Title = null; IRow rows = null; Type entityType = entitys[0].GetType(); PropertyInfo[] entityProperties = entityType.GetProperties(); for (int i = 0; i <= entitys.Count; i++) { if (i == 0) { Title = sheet.CreateRow(0); for (int k = 1; k < title.Length + 1; k++) { Title.CreateCell(0).SetCellValue("序号"); Title.CreateCell(k).SetCellValue(title[k - 1]); } continue; } else { rows = sheet.CreateRow(i); object entity = entitys[i - 1]; for (int j = 1; j <= entityProperties.Length; j++) { object[] entityValues = new object[entityProperties.Length]; entityValues[j - 1] = entityProperties[j - 1].GetValue(entity); rows.CreateCell(0).SetCellValue(i); rows.CreateCell(j).SetCellValue(entityValues[j - 1].ToString()); } } } byte[] buffer = new byte[1024 * 2]; using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); buffer = ms.ToArray(); ms.Close(); } return buffer; }
这个函数需要两个参数,一个是要导出的list,一个是表头,假设我们表头有三十个,那我们写表头都崩溃了。
但是我们的实体的属性是一定会写的,所以这个时候就需要我们改造一下了:
首先我们先去获取实体属性的description描述,相信这个在我们建立实体属性的时候就已经写好了,就不用写第二次了。
/// <summary> /// 获取描述 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> private static string GetEnumDescription(PropertyInfo obj) { DescriptionAttribute descAttr = Attribute.GetCustomAttribute(obj, typeof(DescriptionAttribute)) as DescriptionAttribute; if (descAttr == null) { return string.Empty; } return descAttr.Description; }
可以看到我们将属性信息传入进去就可以获取了,只要不是导出超大的excel这里使用的反射可以忽略不计,
然后看看改造之后的代码:
/// <summary> /// 导出不需要表头 /// </summary> /// <param name="entitys"></param> /// <param name="title"></param> /// <returns></returns> public static byte[] OutputFileOutofTitle(List<T> entitys) { IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet("sheet"); IRow Title = null; IRow rows = null; if (entitys.Count == 0) { Type entityType = entitys[0].GetType(); PropertyInfo[] entityProperties = entityType.GetProperties(); Title = sheet.CreateRow(0); for (int k = 1; k < entityProperties.Length + 1; k++) { Title.CreateCell(0).SetCellValue("序号"); Title.CreateCell(k).SetCellValue(GetEnumDescription(entityProperties[k - 1])); } } else { Type entityType = entitys[0].GetType(); PropertyInfo[] entityProperties = entityType.GetProperties(); for (int i = 0; i <= entitys.Count; i++) { if (i == 0) { Title = sheet.CreateRow(0); for (int k = 1; k < entityProperties.Length + 1; k++) { Title.CreateCell(0).SetCellValue("序号"); Title.CreateCell(k).SetCellValue(GetEnumDescription(entityProperties[k - 1])); } continue; } else { rows = sheet.CreateRow(i); object entity = entitys[i - 1]; for (int j = 1; j <= entityProperties.Length; j++) { object[] entityValues = new object[entityProperties.Length]; entityValues[j - 1] = entityProperties[j - 1].GetValue(entity); rows.CreateCell(0).SetCellValue(i); if (entityValues[j - 1] != null) { rows.CreateCell(j).SetCellValue(entityValues[j - 1].ToString()); } } } } } byte[] buffer = new byte[1024 * 2]; using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); buffer = ms.ToArray(); ms.Close(); } return buffer; }
这里直接通过类型获取属性信息,之后再获取属性中的描述,其实挺简单的,记录一下吧,要不然又忘了。