使用 HttpContext.Response 將 GridView 渲染為 HTML 再匯出 .xls,開啟 Excel 顯示亂碼。根因在於 ContentEncoding 與 Charset 不匹配,以及 Excel 對 HTML 內容編碼的自動偵測機制。
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF7; // ❌ 錯誤:UTF-7
HttpContext.Current.Response.Write(sb.ToString());
Charset = "UTF-8" 告訴瀏覽器/Excel 內容為 UTF-8。ContentEncoding = UTF7 實際將字串以 UTF-7 位元組寫入輸出流。Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "UTF-8";
Response.ContentEncoding = System.Text.Encoding.UTF8; // ✅ 一致
Response.Write(sb.ToString());
Response.ContentEncoding = new UTF8Encoding(true); // true = emit BOM
// 或手動寫入 BOM
byte[] bom = Encoding.UTF8.GetPreamble();
Response.BinaryWrite(bom);
Response.Write(sb.ToString());
application/vnd.ms-excel,.xlsx 對應 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(需 OpenXML SDK 產生真實 xlsx)。public static void ExportExcel(string fileName, GridView gv) {
gv.EnableViewState = false;
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
using (var htw = new HtmlTextWriter(sw)) {
var page = new Page();
var form = new HtmlForm();
page.EnableEventValidation = false;
page.DesignerInitialize();
page.Controls.Add(form);
form.Controls.Add(gv);
page.RenderControl(htw);
}
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Current.Response.AddHeader("Content-Disposition",
"attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8) + ".xls");
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8; // 關鍵:與 Charset 一致
HttpContext.Current.Response.Write(sb.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
HTML 偽裝 .xls 會被 Excel 警告「檔案格式與副檔名不符」。正式專案建議使用 DocumentFormat.OpenXml 產生標準 xlsx,無編碼困擾、支援樣式、公式、大數據量。
ContentEncoding 必須與 Charset 編碼一致。HttpUtility.UrlEncode(fileName, Encoding.UTF8)。Response.End() 會拋 ThreadAbortException,在 try-catch 中忽略即可。修正編碼一致性後,匯出 Excel 亂碼問題即刻解決。