[C#] 匯出IEnumerable<T>至Excel
前言
匯出Excel檔案是一個很常見的需求,
通常我們都會需要將Gridview中的資料匯出成Excel檔,
除了在Asp.Net中常見的直接使用Response.Write匯出之外,
我們也可以使用NPOI的Library來動態產生Excel檔案以供下載,
所以今天希望可以替IEnumerable<T>撰寫一個擴充方法,
來動態的產生Excel檔案,並能夠根據Attribute修改欄位名稱,
在AP或Web上都能夠通用
實際演練
首先,我們先準備一個欲匯出資料的Class,
並且我們引用System.ComponentDataModel.DataAnnotations的dll,
替我們的Class加上DisplayName,也就是我們所希望顯示的Title名稱
[DisplayName("員工資料")]
public class PersonData
{
[DisplayName("員工序號")]
public int Sn { get; set; }
[DisplayName("員工姓名")]
public string Name { get; set; }
[DisplayName("員工生日")]
public DateTime BirthDay { get; set; }
}
接著,我們來替IEnumerable<T>撰寫擴充方法,
使得IEnumerable<T>都擁有匯出Excel的能力,
在這邊使用了NPOI Library,請大家記得引用相關的dll
(NPOI, NPOI.HSSF, NPOI.POIFS, NPOI.Util)
public static class ExportExcelExtensions
{
public static void ExportExcel<T>(this IEnumerable<T> dataList, string fileName)
{
//Create workbook
var datatype = typeof(T);
var workbook = new HSSFWorkbook();
var worksheet = workbook.CreateSheet(string.Format("{0}", datatype.GetDisplayName()));
//Insert titles
var row = worksheet.CreateRow(0);
var titleList = datatype.GetPropertyDisplayNames();
for (int i = 0; i < titleList.Count; i++)
{
row.CreateCell(i).SetCellValue(titleList[i]);
}
//Insert data values
for (int i = 1; i < dataList.Count() + 1; i++)
{
var tmpRow = worksheet.CreateRow(i);
var valueList = dataList.ElementAt(i - 1).GetPropertyValues();
for (int j = 0; j < valueList.Count; j++)
{
tmpRow.CreateCell(j).SetCellValue(valueList[j]);
}
}
//Save file
FileStream file = new FileStream(fileName, FileMode.Create);
workbook.Write(file);
file.Close();
}
public static string GetDisplayName(this MemberInfo memberInfo)
{
var titleName = string.Empty;
//Try get DisplayName
var attribute = memberInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault();
if (attribute != null)
{
titleName = (attribute as DisplayNameAttribute).DisplayName;
}
//If no DisplayName
else
{
titleName = memberInfo.Name;
}
return titleName;
}
public static List<string> GetPropertyDisplayNames(this Type type)
{
var titleList = new List<string>();
var propertyInfos = type.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
var titleName = propertyInfo.GetDisplayName();
titleList.Add(titleName);
}
return titleList;
}
public static List<string> GetPropertyValues<T>(this T data)
{
var propertyValues = new List<string>();
var propertyInfos = data.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
propertyValues.Add(propertyInfo.GetValue(data, null).ToString());
}
return propertyValues;
}
}
ExportExcel : 用來匯出Excel檔案
GetDisplayName : 取得DisplayNameAttribute中所設定的名稱
GetPropertyDisplayNames : 取得Property的顯示名稱,用來當作標題
GetPropertyValues : 取得Property的值
使用範例:
var dataList = new List<PersonData>()
{
new PersonData(){Sn=1,Name="John",BirthDay=new DateTime(1985,6,8)},
new PersonData(){Sn=2,Name="David",BirthDay=new DateTime(1979,2,14)},
new PersonData(){Sn=3,Name="Steve",BirthDay=new DateTime(1988,3,9)},
};
dataList.ExportExcel("Test.xls");
匯出結果 :
結語
當然這個擴充方法還可以依照更進一步的需求作變更,
比如說顯示格式,欄位寬度,或是挑選欲顯示屬性等等,
大家可以依照自己的需求作擴充,
如果有任何問題請跟我說 ^^