首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

.NET 匯出 Excel 總整理:ASP.NET 五大方案 + WinForms 兩大方案完整代碼與選型指南

     編輯:ASP.NET 基礎

專案需求「匯出 Excel」看似簡單,實則因架構(Web/桌面)、資料量、樣式需求、部署環境不同,最佳方案大相逕庭。本文系統整理 **ASP.NET 五種主流方案** 與 **WinForms 兩種方案**,附完整可用代碼、優缺點比較表與選型決策樹,助你一分鐘鎖定正確實作。

第一部分:ASP.NET 環境五大方案

方案 1:整頁 HTML 直接輸出(最簡單、最粗暴)

將整個頁面(含按鈕、分頁、圖片)以 application/vnd.ms-excel 輸出。

Response.Clear();
Response.Buffer = true;
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", $"attachment;filename=Export_{DateTime.Now:yyyyMMdd}.xls");
this.EnableViewState = false;
// 頁面正常 Render,所有 HTML 皆進入 Excel

✅ 零代碼改動 ❌ 匯出垃圾標籤、樣式混亂、分頁器也進去

方案 2:DataGrid/GridView 控制項渲染(經典 WebForms 做法)

只匯出特定控制項的資料,解決方案 1 的雜訊問題。

public void ExportControl(Control ctrl, string fileName)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Buffer = true;
    HttpContext.Current.Response.Charset = "UTF-8";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Default;
    HttpContext.Current.Response.ContentType = "application/ms-excel";
    HttpContext.Current.Response.AddHeader("Content-Disposition", $"attachment;filename={HttpUtility.UrlEncode(fileName)}.xls");
    ctrl.Page.EnableViewState = false;

    using (StringWriter sw = new StringWriter())
    using (HtmlTextWriter hw = new HtmlTextWriter(sw))
    {
        ctrl.RenderControl(hw);
        HttpContext.Current.Response.Write(sw.ToString());
    }
    HttpContext.Current.Response.End();
}

⚠️ 需在頁面覆寫 VerifyRenderingInServerForm;若控制項有分頁,僅匯出當頁。

方案 3:DataSet/DataTable 手工組裝 HTML Table(靈活、無控制項相依)

直接遍歷 DataTable 產生 <table>,適合非 WebForms 或需自訂欄位順序/格式。

public void ExportDataTable(DataTable dt, string fileName)
{
    HttpResponse resp = HttpContext.Current.Response;
    resp.Clear();
    resp.Buffer = true;
    resp.Charset = "GB2312"; // 中文環境常用
    resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
    resp.ContentType = "application/vnd.ms-excel";
    resp.AddHeader("Content-Disposition", $"attachment;filename={HttpUtility.UrlEncode(fileName)}.xls");

    // 標題列
    for (int i = 0; i < dt.Columns.Count; i++)
        resp.Write(dt.Columns[i].ColumnName + (i == dt.Columns.Count - 1 ? "\n" : "\t"));

    // 資料列
    foreach (DataRow row in dt.Rows)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
            resp.Write(row[i].ToString() + (i == dt.Columns.Count - 1 ? "\n" : "\t"));
    }
    resp.End();
}

✅ 完整資料、無分頁限制 ❌ 無樣式、大數據量字串拼接效能差

方案 4:DataView + Excel COM Interop 產生真實 .xls(伺服器端自動化)

在伺服器啟動 Excel Application 寫入、格式化、存檔、再傳檔給客戶端。

// 關鍵片段(完整代碼極長,見原文)
Application excel = new ApplicationClass();
_Workbook wb = excel.Workbooks.Add(true);
_Worksheet ws = (_Worksheet)wb.ActiveSheet;
// ... 寫入標題、資料、設定格式、邊框、合併儲存格、自動欄寬 ...
wb.SaveCopyAs(serverPath);
excel.Quit();
// 釋放 COM 物件(關鍵!否則 Excel.exe 殘留)
Marshal.ReleaseComObject(ws); Marshal.ReleaseComObject(wb); Marshal.ReleaseComObject(excel);
GC.Collect();
// 傳檔下載
Response.WriteFile(serverPath);

✅ 真實 .xls、完整格式控制 ❌ **伺服器必裝 Office、COM 相容性地獄、效能極差、不支援高併發、微軟明確不建議伺服器端自動化 Office**

方案 5:先存檔伺服器再下載(持久化、可斷點續傳)

將 Excel 檔案產生到伺服器磁碟(或雲端儲存),再以 Response.WriteFile 或提供下載連結。

string path = Server.MapPath("~/Exports/Report_" + Guid.NewGuid() + ".csv");
using (FileStream fs = new FileStream(path, FileMode.Create))
using (StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding("GB2312")))
{
    sw.WriteLine("編號,姓名,年齡");
    foreach (DataRow dr in dt.Rows)
        sw.WriteLine($"{dr["ID"]},{dr["Name"]},{dr["Age"]}");
}
Response.Clear();
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-Disposition", $"attachment;filename={HttpUtility.UrlEncode(Path.GetFileName(path))}");
Response.WriteFile(path);
Response.End();

✅ 可保留歷史檔案、支援大檔分段下載 ❌ 需管理磁碟空間、清理策略


第二部分:WinForms 環境兩大方案

方案 A:CSV 文字檔 + Process.Start 開啟(最輕量、無 Office 相依)

string csvPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Export_" + DateTime.Now.Ticks + ".csv");
using (StreamWriter sw = new StreamWriter(csvPath, false, Encoding.GetEncoding("GB2312")))
{
    sw.WriteLine("自動編號,姓名,年齡");
    foreach (DataRow dr in dt.Rows)
        sw.WriteLine($"{dr["ID"]},{dr["Name"]},{dr["Age"]}");
}
Process.Start(csvPath); // 系統預設關聯 Excel 開啟

方案 B:Excel Interop 完整自動化(需用戶端安裝 Office、功能最強)


Excel.Application xlApp = new Excel.Application();
xlApp.Visible = false; xlApp.DisplayAlerts = false;
Excel.Workbook wb = xlApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1];

// 寫入標題
for (int c = 0; c < dt.Columns.Count; c++)
{
    ws.Cells[2, c + 1] = dt.Columns[c].ColumnName;
    Excel.Range rng = (Excel.Range)ws.Cells[2, c + 1];
    rng.Font.Bold = true; rng.Interior.ColorIndex = 15;
}

// 寫入資料
for (int r = 0; r < dt.Rows.Count; r++)
    for (int c = 0; c < dt.Columns.Count; c++)
        ws.Cells[r + 3, c + 1] = dt.Rows[r][c].ToString();

// 邊框、自動欄寬、存檔
Excel.Range all = ws.get_Range(ws.Cells[2,1], ws.Cells[dt.Rows.Count+2, dt.Columns.Count]);
all.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
all.Columns.AutoFit();

SaveFileDialog sfd = new SaveFileDialog { Filter = "Excel檔案|*.xlsx", DefaultExt = "xlsx" };
if (sfd.ShowDialog() == DialogResult.OK)
    wb.SaveAs(sfd.FileName, Excel.XlFileFormat.xlOpenXMLWorkbook);

wb.Close(false); xlApp.Quit();
// 釋放 COM
Marshal.ReleaseComObject(ws); Marshal.ReleaseComObject(wb); Marshal.ReleaseComObject(xlApp);
GC.Collect();

選型決策樹(30 秒鎖定方案)

  1. ASP.NET 專案?
    • 是 → 需真實 .xlsx、樣式/公式/大數據? → EPPlus / NPOI / OpenXML SDK(首選,純 .NET、高效能、無 Office 相依)
    • 否 → 快速原型、資料量小、無樣式需求? → 方案 3:DataTable 手工 HTML Table
    • 否 → 既有 GridView、只匯出當頁、不想引新套件? → 方案 2:控制項 RenderControl
    • 否 → 需保留歷史檔、支援斷點續傳? → 方案 5:存檔再下載
    • 嚴禁方案 4(伺服器 COM Interop),除非極特殊單機內網且已評估風險。
  2. WinForms 專案?
    • 用戶端保證裝 Office、需複雜格式/圖表/巨集? → 方案 B:Interop 自動化(記得釋放 COM)
    • 否 → 只需資料可被 Excel 開啟、跨平台相容? → 方案 A:CSV + Process.Start
    • 現代替代:ClosedXML / EPPlus 寫入 MemoryStream → SaveFileDialog 存檔,無 Office 相依、API 友善、效能佳。

避坑金句

  • Web 伺服器絕不裝 Office 做自動化:微軟 KB 257757 明確警告記憶體洩漏、安全性、授權、穩定性風險。
  • 大量資料(>5萬列)勿用 HTML Table/字串拼接:改用 OpenXML/EPPlus 串流寫入,避免 OOM。
  • 中文檔名必須 UrlEncode:HttpUtility.UrlEncode(fileName, Encoding.UTF8),否則 IE/Edge 下載檔名亂碼。
  • Response.End() 會拋 ThreadAbortException:在 try/catch 中忽略,或改用 HttpContext.Current.ApplicationInstance.CompleteRequest()。

掌握這張地圖,下次接到「匯出 Excel」需求,你就能根據專案實況,在五分鐘內選定並實作最適合的方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved