### 目前適用於WebForm,MVC的話在最後Response處需稍做調整
#### 只要傳List&Class或DataTable就能透過NPOI轉成報表
##### 用法
※List或DataTable通常會由Dapper或SQLCommand撈出資料
1. 傳入List包含泛型Class輸出Excel
```
List<Vw_CarWatch> vw_Cars = new List<Vw_CarWatch>();
NPOIHelper.ExportExcel<Vw_CarWatch>(vw_Cars, "車牌辨識清冊.xlsx");
```
Class要包含DisplayName Attribute,Excel才會輸出
(標題DisplayName為必要,若欄位沒有要在Excel上輸出則不加)
```
[DisplayName("車牌辨識清冊")]
public partial class Vw_CarWatch
{
public long ID { get; set; }
[DisplayName("進場時間")]
public DateTime InsTime { get; set; }
[DisplayName("辨識車號")]
public string CarNo { get; set; }
[DisplayName("辨識車尾")]
public string TailNo { get; set; }
public string FileName { get; set; }
}
```
2. 傳入DataTable輸出Excel
```
DataTable dt = new DataTable();
NPOIHelper.ExportDataTableToExcelNPOI(dt, "進出車輛清單.xlsx");
```
3. 傳入GridView輸出Excel(WebForm限定)
```
NPOIHelper.ExportGridViewToExcelNPOI(gv_DataList,"車輛清單");
```
##### 原始碼
```
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI.WebControls;
/// <summary>
/// NPOIHelper 的摘要描述
/// </summary>
public static class NPOIHelper
{
public static void ExportExcel<T>(this IEnumerable<T> dataList, string fileName)
{
//Create workbook
var datatype = typeof(T);
var workbook = new XSSFWorkbook();
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(titleList);
for (int j = 0; j < valueList.Count; j++)
{
DateTime dt = new DateTime();
if (DateTime.TryParse(valueList[j], out dt))
{
//Excel日期、時間轉換
var _cell = tmpRow.CreateCell(j);
XSSFCellStyle styleDate = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
styleDate.DataFormat = valueList[j].Split(':').Count() > 1
? format.GetFormat("HH:mm") //時間
: format.GetFormat("yyyy/mm/dd");//日期
_cell.CellStyle = styleDate;
_cell.SetCellValue(dt);//日期
}
else
tmpRow.CreateCell(j).SetCellValue(valueList[j]);
}
}
//Set OK AutoSize
for (int i = 0; i < titleList.Count; i++)
{
worksheet.AutoSizeColumn(i);
}
using (MemoryStream MS = new MemoryStream())
{
workbook.Write(MS);
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
System.Web.HttpContext.Current.Response.BinaryWrite(MS.ToArray());
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();
}
}
private 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
{
//Pass Display
titleName = "";//memberInfo.Name;
}
return titleName;
}
private 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();
if (!string.IsNullOrWhiteSpace(titleName))
titleList.Add(titleName);
}
return titleList;
}
private static List<string> GetPropertyValues<T>(this T data, List<string> titleList)
{
var propertyValues = new List<string>();
var propertyInfos = data.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//判斷Class是否有DisplayName
//與標題交叉比對(LINQ)
if (propertyInfo.CustomAttributes.Count() > 0
&& titleList.Any(x => x.ToString() == propertyInfo.GetDisplayName()))
{
var Value = propertyInfo.GetValue(data, null);
if (Value == null)
Value = "";
propertyValues.Add(Value.ToString());
}
}
return propertyValues;
}
public static void ExportDataTableToExcelNPOI(DataTable pDataTable, string strExportFileName, string SheetName = "")
{
int tRowCount = pDataTable.Rows.Count;
int tColumnCount = pDataTable.Columns.Count;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
XSSFWorkbook workbook = new XSSFWorkbook();
ISheet u_sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(SheetName) ? "工作表1" : SheetName);
IRow u_row1 = u_sheet.CreateRow(0);
XSSFCellStyle styleRow1 = (XSSFCellStyle)workbook.CreateCellStyle();
for (int i = 1; i <= pDataTable.Columns.Count - 1; i++)
{
u_row1.CreateCell(i - 1).SetCellValue(pDataTable.Columns[i].ColumnName);
}
for (int j = 0; j < tRowCount; j++)
{
int x = 1;
IRow u_row = u_sheet.CreateRow(j + 1);
for (int k = 0; k < tColumnCount - 1; k++)
{
u_sheet.AutoSizeColumn(j); //自動調整欄寬
if (x != 5)
{
u_row.CreateCell(k).SetCellValue(pDataTable.Rows[j][x].ToString().Replace(" ", ""));
x++;
}
}
}
//== 輸出Excel 2007檔案。==============================
MemoryStream MS = new MemoryStream(); //==需要 System.IO命名空間
workbook.Write(MS);
//== Excel檔名,請寫在最後面 filename的地方
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + strExportFileName);
HttpContext.Current.Response.BinaryWrite(MS.ToArray());
//== 釋放資源
workbook = null; //== VB為 Nothing
MS.Close();
MS.Dispose();
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
/// <summary>
/// GridView下載
/// </summary>
/// <param name="gv"></param>
/// <param name="exportFileName"></param>
/// <param name="sheetName"></param>
public static void ExportGridViewToExcelNPOI(GridView gv, string exportFileName, string sheetName = "")
{
if (string.IsNullOrWhiteSpace(sheetName))
{
sheetName = exportFileName;
}
//建立 WorkBook 及試算表
XSSFWorkbook workbook = new XSSFWorkbook();
MemoryStream ms = new MemoryStream();
XSSFSheet mySheet1 = (XSSFSheet)workbook.CreateSheet(sheetName);
//建立標題列 Header
XSSFRow rowHeader = (XSSFRow)mySheet1.CreateRow(0);
for (int i = 0; i < gv.HeaderRow.Cells.Count; i++)
{
string strValue = gv.HeaderRow.Cells[i].Text;
XSSFCell cell = (XSSFCell)rowHeader.CreateCell(i);
cell.SetCellValue(HttpUtility.HtmlDecode(strValue).Trim());
//建立新的CellStyle
ICellStyle CellsStyle = workbook.CreateCellStyle();
//建立字型
IFont StyleFont = workbook.CreateFont();
//設定文字字型
StyleFont.FontName = "微軟正黑體";
//設定文字大小
StyleFont.FontHeightInPoints = 12; //設定文字大小為10pt
CellsStyle.SetFont(StyleFont);
cell.CellStyle = CellsStyle;
mySheet1.AutoSizeColumn(i);
}
//建立內容列 DataRow
for (int i = 0; i < gv.Rows.Count; i++)
{
XSSFRow rowItem = (XSSFRow)mySheet1.CreateRow(i + 1);
for (int j = 0; j < gv.HeaderRow.Cells.Count; j++)
{
Label lb = null; // 因為GridView中有TemplateField,所以要將Label.Text讀出來
if (gv.Rows[i].Cells[j].Controls.Count > 1)
{
lb = gv.Rows[i].Cells[j].Controls[1] as Label;
}
string value1 = (lb != null)
? HttpUtility.HtmlDecode(lb.Text)
: HttpUtility.HtmlDecode(gv.Rows[i].Cells[j].Text).Trim();
int intry = 0;
bool isNumeric = !value1.StartsWith("0") && int.TryParse(value1, out intry);
XSSFCell cell = (XSSFCell)rowItem.CreateCell(j);
if (string.IsNullOrEmpty(value1.Trim()))
{
//空白
cell.SetCellValue(Convert.ToString(""));
}
else if (!isNumeric)
{
XSSFCellStyle cellStyle = (XSSFCellStyle)workbook.CreateCellStyle(); // 給cell style
XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
cellStyle.DataFormat = format.GetFormat("@"); // 文字格式
//建立字型
IFont StyleFont = workbook.CreateFont();
//設定文字字型
StyleFont.FontName = "微軟正黑體";
//設定文字大小
StyleFont.FontHeightInPoints = 12; //設定文字大小為12pt
cellStyle.SetFont(StyleFont);
//cellStyle.WrapText = true; //文字自動換列
cell.CellStyle = cellStyle;
cell.SetCellValue(value1);
}
else
{
//數字格式
cell.SetCellValue(intry);
////自訂呈現格式
//XSSFCellStyle cellStyle = (XSSFCellStyle)workbook.CreateCellStyle(); // 給cell style
//XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
//cellStyle.DataFormat = format.GetFormat("#,##0;[RED](#,##0)");
//cell.CellStyle = cellStyle;
}
}
}
//匯出
workbook.Write(ms);
// 此為匯出副檔名xlsx
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("Content-Disposition",
string.Format("attachment;filename={0}", $"{exportFileName}.xlsx"));
HttpContext.Current.Response.BinaryWrite(ms.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
//釋放資源
workbook = null;
ms.Close();
ms.Dispose();
}
}
```