在 ASP.NET 中匯出 Excel 主要有兩種思路:一是將檔案暫存於伺服器再提供下載連結;二是直接將檔案流輸出至瀏覽器。回應輸出時,\t 相當於分欄,\n 相當於換列。
此法會將頁面所有元素(按鈕、表格、圖片等)一併匯出。
Response.Clear();
Response.Buffer = true;
Response.AppendHeader("Content-Disposition", "attachment;filename=" + DateTime.Now.ToString("yyyyMMdd") + ".xls");
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "application/vnd.ms-excel";
this.EnableViewState = false;
關鍵在於將 ContentType 設為 application/vnd.ms-excel,瀏覽器便會提示下載儲存。同理,設為 image/JPEG、text/HTML、image/GIF、msword 可分別輸出圖片、網頁、Word 文件。
僅匯出 DataGrid 顯示的資料,避免多餘 HTML 元素。
System.Web.UI.Control ctl = this.DataGrid1;
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=Excel.xls");
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default;
HttpContext.Current.Response.ContentType = "application/ms-excel";
ctl.Page.EnableViewState = false;
System.IO.StringWriter tw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
ctl.RenderControl(hw);
HttpContext.Current.Response.Write(tw.ToString());
HttpContext.Current.Response.End();
若 DataGrid 啟用分頁,僅會匯出當前頁資料。為方便重用,可封裝為方法:
public void DGToExcel(System.Web.UI.Control ctl) { /* 同上邏輯 */ }
將 DataTable 的各列標題與資料列以 \t、\n 格式寫入回應流。
public void CreateExcel(DataSet ds, string FileName) {
HttpResponse resp = Page.Response;
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
DataTable dt = ds.Tables[0];
DataRow[] myRow = dt.Select();
int cl = dt.Columns.Count;
string colHeaders = "";
for (int i = 0; i < cl; i++) {
colHeaders += dt.Columns[i].Caption.ToString() + (i == cl - 1 ? "\n" : "\t");
}
resp.Write(colHeaders);
foreach (DataRow row in myRow) {
string ls_item = "";
for (int i = 0; i < cl; i++) {
ls_item += row[i].ToString() + (i == cl - 1 ? "\n" : "\t");
}
resp.Write(ls_item);
}
resp.End();
}
透過 Excel COM 物件建立活頁簿,支援標題置中、日期格式、邊框、自動欄寬、合計列等豐富排版。
public void OutputExcel(DataView dv, string str) {
GC.Collect();
Application excel = new ApplicationClass();
_Workbook xBk = excel.Workbooks.Add(true);
_Worksheet xSt = (_Worksheet)xBk.ActiveSheet;
int rowIndex = 4, colIndex = 1;
// 寫入標題
foreach (DataColumn col in dv.Table.Columns) {
colIndex++;
excel.Cells[4, colIndex] = col.ColumnName;
xSt.get_Range(excel.Cells[4, colIndex], excel.Cells[4, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
}
// 寫入資料
foreach (DataRowView row in dv) {
rowIndex++; colIndex = 1;
foreach (DataColumn col in dv.Table.Columns) {
colIndex++;
if (col.DataType == typeof(DateTime)) {
excel.Cells[rowIndex, colIndex] = Convert.ToDateTime(row[col.ColumnName]).ToString("yyyy-MM-dd");
} else if (col.DataType == typeof(string)) {
excel.Cells[rowIndex, colIndex] = "'" + row[col.ColumnName].ToString();
} else {
excel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
}
xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
}
}
// 合計列、邊框、自動欄寬、儲存與下載...
// 釋放 COM 物件
System.Runtime.InteropServices.Marshal.ReleaseComObject(xSt);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xBk);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
GC.Collect();
}
將資料寫入 CSV 暫存檔,再透過 Response.WriteFile 提供下載,適合需保留匯出紀錄的場景。
開啟預設範本,寫入資料後另存新檔,最後關閉 Excel 並釋放資源。
public void Out2Excel(string sTableName, string url) {
Excel.Application oExcel = new Excel.Application();
oExcel.Visible = false; oExcel.DisplayAlerts = false;
Workbooks oBooks = oExcel.Workbooks;
Workbook oBook = oBooks.Open(url + "\\MyTemplate.xls", ...);
Worksheet oSheet = (Worksheet)oBook.Worksheets[1];
oSheet.Name = "Sheet1";
DumpData(dt, oSheet.Cells);
oSheet.SaveAs(url + "\\myExcel.xls", Excel.XlFileFormat.xlTemplate, ...);
oBook.Close(false, ...); oExcel.Quit(); GC.Collect(); KillProcess("Excel");
}
建立新活頁簿,寫入標題與資料,顯示進度,最後由使用者決定儲存路徑。
protected void ExportExcel() {
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.DefaultExt = "xls"; saveDialog.Filter = "Excel文件|*.xls";
if (saveDialog.ShowDialog() != DialogResult.OK) return;
Excel.Application xlApp = new Excel.Application();
Excel.Workbook workbook = xlApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];
// 寫入標題、資料、設定邊框...
worksheet.SaveAs(saveFileName, ...); workbook.Close(...); xlApp.Quit();
}
ASP.NET 在伺服端以串流輸出;WinForm 在客戶端呼叫本機 Excel COM 元件寫入活頁簿,架構差異需注意。