記得第一篇文章就是.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; }
這里直接通過類型獲取屬性信息,之后再獲取屬性中的描述,其實挺簡單的,記錄一下吧,要不然又忘了。