CSV 匯出最常見坑:**中文亂碼**。根因在於 Excel 開啟 CSV 時的編碼判斷邏輯。本文提供兩種經實測有效的解決方案。
string filePath = Server.MapPath("~/exports/data.csv");
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding("GB2312"))) // 或 new UTF8Encoding(true) 加 BOM
{
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={Server.UrlEncode(Path.GetFileName(filePath))}");
Response.WriteFile(filePath);
Response.End();
string fileName = $"Export_{DateTime.Now:yyyyMMddHHmmss}.csv";
Response.Clear();
Response.Buffer = true;
Response.Charset = "GB2312"; // 或 UTF-8
Response.ContentEncoding = Encoding.GetEncoding("GB2312"); // 關鍵:指定輸出編碼
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-Disposition", $"attachment; filename={fileName}");
// 手動寫入 UTF-8 BOM(若用 UTF-8)
// Response.BinaryWrite(new byte[] { 0xEF, 0xBB, 0xBF });
StringBuilder sb = new StringBuilder();
sb.AppendLine("id,name");
sb.AppendLine("1,張三");
sb.AppendLine("2,李四");
sb.AppendLine("3,John Doe");
Response.Write(sb.ToString());
Response.Flush();
Response.End();
| 環境 | 推薦編碼 | BOM | Excel 開啟行為 |
|---|---|---|---|
| 台灣/香港繁中 | Big5 / CP950 | 不需要 | 預設正確 |
| 大陸簡中 | GB2312 / CP936 | 不需要 | 預設正確 |
| 跨地區/現代系統 | UTF-8 | 必要 | 無 BOM 會誤判為 ANSI 導致亂碼 |
| 寫法 | 編碼 | BOM | 備註 |
|---|---|---|---|
| `new StreamWriter(fs, Encoding.UTF8)` | UTF-8 | **無** | 預設不寫 BOM |
| `new StreamWriter(fs, new UTF8Encoding(true))` | UTF-8 | **有** | `encoderShouldEmitUTF8Identifier=true` |
| `Encoding.GetEncoding("GB2312")` | GB2312 | 不適用 | Excel 內建支援 |
| `Response.ContentEncoding = Encoding.UTF8` + `Response.BinaryWrite(BOM)` | UTF-8 | 手動加 | 直接輸出模式 |
Response.Clear();
Response.Buffer = true;
Response.ContentEncoding = Encoding.UTF8;
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=export.csv");
// 寫入 BOM
Response.BinaryWrite(new byte[] { 0xEF, 0xBB, 0xBF });
Response.Write("編號,姓名,部門\n");
Response.Write("1,王小明,資訊部\n");
Response.Write("2,陳大華,業務部\n");
Response.Flush();
Response.End();
掌握「編碼明確指定 + UTF-8 必加 BOM」雙重保險,即可徹底解決 CSV 中文亂碼,確保資料在各地區、各工具下正確呈現。