三種主流匯出策略
| 策略 | 優點 | 缺點 | 適用場景 |
| Interop (COM 自動化) | 完整支援 Excel/Word 所有功能、格式精確 | 需安裝 Office、效能差、伺服器端不支援、記憶體洩漏風險 | 桌面應用、小量資料、需複雜排版 |
| HTML/CSV 字串輸出 | 零依賴、極快、跨平台、瀏覽器可直接開啟 | 格式受限(無公式、樞紐分析)、大數字可能被科學記號 | Web 匯出、大量資料、簡單表格 |
| Open XML SDK / NPOI / EPPlus | 無需 Office、支援 .xlsx/.docx 完整功能、效能佳 | 學習曲線較陡、樞紐/圖表支援不一 | 伺服器端、生產環境、長期維護專案 |
方案一:HTML 字串輸出(最簡單、Web 首選)
public void ExportToExcel(DataSet ds, string fileName)
{
var dt = ds.Tables[0];
var sb = new StringBuilder();
sb.Append("");
// 標題列
sb.Append("");
foreach (DataColumn col in dt.Columns) sb.Append($"| {col.ColumnName} | ");
sb.Append("
");
// 資料列
foreach (DataRow row in dt.Rows)
{
sb.Append("");
foreach (DataColumn col in dt.Columns) sb.Append($"| {row[col]} | ");
sb.Append("
");
}
sb.Append("
");
Response.Clear();
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", $"attachment;filename={fileName}.xls");
Response.ContentEncoding = Encoding.UTF8;
Response.Write(sb.ToString());
Response.End();
}
方案二:Open XML SDK 建立真正的 .xlsx(推薦生產環境)
// NuGet: DocumentFormat.OpenXml
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
public byte[] GenerateXlsx(DataSet ds)
{
using (var ms = new MemoryStream())
using (var doc = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
var wbPart = doc.AddWorkbookPart();
wbPart.Workbook = new Workbook();
var wsp = wbPart.AddNewPart();
wsp.Worksheet = new Worksheet(new SheetData());
wbPart.Workbook.AppendChild(new Sheets(
new Sheet { Id = wbPart.GetIdOfPart(wsp), SheetId = 1, Name = "Sheet1" }));
var sheetData = wsp.Worksheet.GetFirstChild();
var dt = ds.Tables[0];
// 標題列
var headerRow = new Row();
foreach (var col in dt.Columns) headerRow.Append(new Cell { CellValue = new CellValue(col.ColumnName), DataType = CellValues.String });
sheetData.Append(headerRow);
// 資料列
foreach (DataRow row in dt.Rows)
{
var r = new Row();
foreach (DataColumn col in dt.Columns)
r.Append(new Cell { CellValue = new CellValue(row[col]?.ToString() ?? ""), DataType = CellValues.String });
sheetData.Append(r);
}
wbPart.Workbook.Save();
return ms.ToArray();
}
}
方案三:NPOI 相容 .xls/.xlsx(程式碼簡潔)
// NuGet: NPOI
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
public byte[] GenerateWithNpoi(DataSet ds)
{
IWorkbook wb = new XSSFWorkbook(); // .xlsx
ISheet sheet = wb.CreateSheet("Data");
var dt = ds.Tables[0];
// 標題
IRow header = sheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
header.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
// 資料
for (int r = 0; r < dt.Rows.Count; r++)
{
IRow row = sheet.CreateRow(r + 1);
for (int c = 0; c < dt.Columns.Count; c++)
row.CreateCell(c).SetCellValue(dt.Rows[r][c]?.ToString() ?? "");
}
using (var ms = new MemoryStream())
{
wb.Write(ms);
return ms.ToArray();
}
}
Word 匯出同理:HTML 字串或 Open XML SDK (WordprocessingDocument)
Word 可用 application/vnd.ms-word + HTML 字串快速匯出;正式文件建議 Open XML SDK 操作 DocumentFormat.OpenXml.Wordprocessing。
選型建議
- Web 專案、資料量 < 5 萬列、無複雜格式 → **HTML 字串**
- 伺服器端排程、需 .xlsx 標準格式、長期維護 → **Open XML SDK / NPOI / EPPlus**
- 桌面端、需操作現有樣板、執行巨集 → **Interop**(並嚴格
Marshal.ReleaseComObject)