`,設定 `Content-Type: application/ms-excel`,瀏覽器會以 Excel 開啟。此法**不產生真正 .xlsx**,但相容性極佳、無第三方元件。
完整程式碼
public partial class GridViewExport : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BindGrid();
}
private void BindGrid()
{
string connStr = "Server=.;Database=TestDB;Integrated Security=True;";
string sql = "SELECT TOP 10 * FROM Products";
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(sql, conn))
using (var da = new SqlDataAdapter(cmd))
{
var dt = new DataTable();
da.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
protected void btnExport_Click(object sender, EventArgs e)
{
ExportToExcel("產品清單_" + DateTime.Now.ToString("yyyyMMdd"), GridView1);
}
public void ExportToExcel(string fileName, GridView gv)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
HttpContext.Current.Response.ContentType = "application/ms-excel";
HttpContext.Current.Response.AddHeader("Content-Disposition",
"attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8) + ".xls");
// 關閉 ViewState 避免輸出隱藏欄位
gv.EnableViewState = false;
using (var sw = new StringWriter())
using (var hw = new HtmlTextWriter(sw))
{
gv.RenderControl(hw);
HttpContext.Current.Response.Write(sw.ToString());
}
HttpContext.Current.Response.End();
}
// 必須覆寫,否則 RenderControl 會擲出「控制項必須置於 runat=server 表單內」錯誤
public override void VerifyRenderingInServerForm(Control control) { }
}
前端按鈕
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" />
<asp:Button ID="btnExport" runat="server" Text="匯出 Excel" OnClick="btnExport_Click" />
常見問題與解決
| 問題 | 原因 | 解決 |
| 匯出檔案打開時 Excel 警告「格式不符」 | 實為 HTML 非真實 BIFF/OpenXML | 接受警告即可開啟;需真實 .xlsx 請改用 NPOI/EPPlus |
| 中文亂碼 | 編碼未設定或 UrlEncode 缺失 | 設定 `Response.ContentEncoding = Encoding.UTF8` 並 `UrlEncode` 檔名 |
| 大量資料 (超過 1 萬列) 記憶體爆炸 | StringWriter 累積完整字串 | 改用 `Response.Output.Write` 串流輸出,或分批寫入 |
| 樣式/合併儲存格遺失 | HTML 渲染不支援 Excel 進階功能 | 改用 NPOI/EPPlus 程式化建立 |
進階:使用 NPOI 產生真實 .xlsx (推薦生產環境)
public void ExportXlsx(string fileName, GridView gv)
{
var wb = new XSSFWorkbook();
var sheet = wb.CreateSheet("Sheet1");
var headerRow = sheet.CreateRow(0);
for (int i = 0; i < gv.Columns.Count; i++)
headerRow.CreateCell(i).SetCellValue(gv.Columns[i].HeaderText);
for (int r = 0; r < gv.Rows.Count; r++)
{
var row = sheet.CreateRow(r + 1);
for (int c = 0; c < gv.Columns.Count; c++)
row.CreateCell(c).SetCellValue(gv.Rows[r].Cells[c].Text);
}
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", $"attachment;filename={HttpUtility.UrlEncode(fileName, Encoding.UTF8)}.xlsx");
using (var ms = new MemoryStream())
{
wb.Write(ms);
Response.BinaryWrite(ms.ToArray());
}
Response.End();
}
選型建議
- **簡單報表、資料量 < 5000 列、無樣式需求** → HTML 法 (零相依、極速開發)。
- **正式報表、需樣式/公式/合併儲存格、大量資料** → NPOI / EPPlus / ClosedXML。
- **極大量資料 (10 萬列+)** → `SXSSFWorkbook` (NPOI 串流模式) + 分批寫入 `Response.OutputStream`。
- 上一篇文章: ASP.NET 上傳檔案類型驗證的三種方法:副檔名、MIME、檔頭位元組
- 下一篇文章: ASP.NET 禁用頁面快取的四種方法總結與比較
Copyright ©
程式碼之家 All Rights Reserved