
C# 將 DataGridView 匯出到 Excel 並帶列標題
如何在C#中將DataGridView的資料匯出到Excel並保留欄位標題?
從Windows Forms的DataGridView控制項將資料匯出到Excel格式是一個常見的需求,但開發人員經常會遇到一個令人沮喪的問題:匯出的檔案丟失了欄位標題。 當您需要將DataGridView匯出到Excel並保留欄位標題時,解決方案必須可靠地保留所有的資料和格式。 使用Microsoft Office Interop的傳統方法可能很慢,容易崩潰,並且需要在每台運行此程式碼的機器上安裝MS Excel。
IronXL乾淨地解決了這個問題。 它是一個.NET Excel程式庫,無需任何Office依賴性即可讀取、建立和寫入Excel檔案。 這個教程將引導您完成一個完整的匯出解決方案——一個可以處理欄位標題、資料型別、空單元格和使用者友好檔案保存的解決方案,只需幾行程式碼。
最後,您將擁有一個正常運作的Windows Forms按鈕處理器,將DataGridView匯出到一個帶有所有欄位標題的XLSX檔案中。
在開始之前您需要什麼
在編寫程式碼之前,請確保以下內容已經就緒:
- Visual Studio 2022或更高版本(任何版本)
- 安裝.NET 10 SDK
- 針對.NET 10的Windows Forms應用程式專案
- 可以存取NuGet以安裝IronXL
下面的例子使用頂層語句和現代的.NET 10專案結構。
如何在.NET專案中安裝程式庫?
在Visual Studio中打開NuGet包管理器控制台並運行以下任何一條命令。 該包列在NuGet畫廊中,並針對.NET Standard 2.0及以上,因此它適用於任何現代的.NET專案。
安裝後,在您的表單檔案的頂部新增所需的命名空間:
using IronXL;
using System;
using System.Data;
using System.Windows.Forms;Imports IronXL
Imports System
Imports System.Data
Imports System.Windows.Forms這些導入提供了IronXL的Excel功能、DataTable操作以及匯出過程所需的Windows Forms控制項的存取權限。
如何設置帶有範例資料的DataGridView?
首先在Visual Studio中建立一個Windows Forms應用程式。 通過設計器在主窗體中新增一個名為btnExport的按鈕。 然後填充窗體載入上的表格:
using System;
using System.Data;
using System.Windows.Forms;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
// Define columns -- these names become Excel headers
dt.Columns.Add("Product ID", typeof(int));
dt.Columns.Add("Product Name", typeof(string));
dt.Columns.Add("Price", typeof(decimal));
dt.Columns.Add("Stock Quantity", typeof(int));
// Add sample rows
dt.Rows.Add(1001, "Laptop", 999.99m, 15);
dt.Rows.Add(1002, "Mouse", 29.99m, 50);
dt.Rows.Add(1003, "Keyboard", 79.99m, 30);
dt.Rows.Add(1004, "Monitor", 299.99m, 12);
dt.Rows.Add(1005, "Headphones", 89.99m, 25);
// Bind data to the grid
dataGridView1.DataSource = dt;
}
}Imports System
Imports System.Data
Imports System.Windows.Forms
Public Partial Class Form1
Inherits Form
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt As New DataTable()
' Define columns -- these names become Excel headers
dt.Columns.Add("Product ID", GetType(Integer))
dt.Columns.Add("Product Name", GetType(String))
dt.Columns.Add("Price", GetType(Decimal))
dt.Columns.Add("Stock Quantity", GetType(Integer))
' Add sample rows
dt.Rows.Add(1001, "Laptop", 999.99D, 15)
dt.Rows.Add(1002, "Mouse", 29.99D, 50)
dt.Rows.Add(1003, "Keyboard", 79.99D, 30)
dt.Rows.Add(1004, "Monitor", 299.99D, 12)
dt.Rows.Add(1005, "Headphones", 89.99D, 25)
' Bind data to the grid
dataGridView1.DataSource = dt
End Sub
End Class在dt.Columns.Add(...)呼叫中定義的列名將成為匯出的Excel檔案中的標題行。您可以在此替換任何資料來源——資料庫查詢結果、CSV匯入或者儲存為DataTable的API響應都可以與稍候顯示的匯出程式碼保持一致。 DataTable的方法特別方便,因為DataGridView公開了一個IBindingList,這意味著相同的匯出程式碼可以在每個綁定場景中通用而不需修改。
如果您的DataGridView是由資料庫使用SqlDataAdapter填充的,則DataTable已經包含型別化的列。 將這些型別化的值傳遞給ToString()可以讓數字列在Excel的輸出中保持數字格式,這對於下游報告或資料透視表的使用很重要。
這將建立一個填充了所有資料的DataGridView:

如需更多高級資料綁定場景,請參閱Microsoft關於DataGridView資料綁定的文件以獲取額外範例。
如何在保留欄位標題的同時將DataGridView匯出到Excel?
匯出方法從每個DataGridView列的HeaderText屬性讀取欄位標題,並將它們寫入工作表的第0行。 資料行從第1行開始。 將此方法連接到btnExport單擊事件:
private void btnExport_Click(object sender, EventArgs e)
{
try
{
// Create a new Excel workbook in XLSX format
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet worksheet = workbook.CreateWorkSheet("Exported Data");
// Write column headers to row 0
for (int col = 0; col < dataGridView1.Columns.Count; col++)
{
worksheet.SetCellValue(0, col, dataGridView1.Columns[col].HeaderText);
}
// Write data rows starting at row 1
for (int row = 0; row < dataGridView1.Rows.Count; row++)
{
// Skip the placeholder new-row at the bottom of the grid
if (dataGridView1.AllowUserToAddRows && row == dataGridView1.Rows.Count - 1)
continue;
for (int col = 0; col < dataGridView1.Columns.Count; col++)
{
var cellValue = dataGridView1.Rows[row].Cells[col].Value;
if (cellValue != null)
{
worksheet.SetCellValue(row + 1, col, cellValue.ToString());
}
}
}
// Prompt the user to choose a save location
using SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "Excel Files|*.xlsx",
FileName = "DataGridView_Export.xlsx"
};
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
workbook.SaveAs(saveFileDialog.FileName);
MessageBox.Show("Export completed successfully!", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show($"Export failed: {ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}Private Sub btnExport_Click(sender As Object, e As EventArgs)
Try
' Create a new Excel workbook in XLSX format
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim worksheet As WorkSheet = workbook.CreateWorkSheet("Exported Data")
' Write column headers to row 0
For col As Integer = 0 To dataGridView1.Columns.Count - 1
worksheet.SetCellValue(0, col, dataGridView1.Columns(col).HeaderText)
Next
' Write data rows starting at row 1
For row As Integer = 0 To dataGridView1.Rows.Count - 1
' Skip the placeholder new-row at the bottom of the grid
If dataGridView1.AllowUserToAddRows AndAlso row = dataGridView1.Rows.Count - 1 Then
Continue For
End If
For col As Integer = 0 To dataGridView1.Columns.Count - 1
Dim cellValue = dataGridView1.Rows(row).Cells(col).Value
If cellValue IsNot Nothing Then
worksheet.SetCellValue(row + 1, col, cellValue.ToString())
End If
Next
Next
' Prompt the user to choose a save location
Using saveFileDialog As New SaveFileDialog With {
.Filter = "Excel Files|*.xlsx",
.FileName = "DataGridView_Export.xlsx"
}
If saveFileDialog.ShowDialog() = DialogResult.OK Then
workbook.SaveAs(saveFileDialog.FileName)
MessageBox.Show("Export completed successfully!", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Using
Catch ex As Exception
MessageBox.Show($"Export failed: {ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub拆解匯出步驟
該方法的每一步驟都有特定用途:
- WorkBook.Create:在記憶體中使用XLSX格式初始化一個新的Excel文件。 直到
SaveAs被調用,才會將文件寫入磁碟。 - CreateWorkSheet:新增一個命名的工作表來保存匯出資料。 名稱"匯出資料"將出現在Excel中作為選項卡標籤。
- 欄位標題迴圈:為每個列讀取
dataGridView1.Columns[col].HeaderText並將其寫入行索引0。這是保留標題的關鍵步驟。 - 資料行迴圈:巢狀迴圈遍歷每一行和列,使用
row + 1作為Excel行索引,這樣資料始終位於標題行以下。 - 空值檢查:防止當單元格不包含值時發生異常,這在實資料中很常見。
- SaveFileDialog:允許使用者在運行時選擇文件名和目的地,而不是硬編碼路徑。
匯出的文件看起來如下:

如何在匯出過程中處理常見的邊界案例?
實際世界的数据很少像範例数據集那樣整潔。 以下是您最有可能遇到的場景以及如何解決它們。
空單元格
資料迴圈中的空檢查(if (cellValue != null))在未拋出異常的情況下處理空單元格。 在Excel輸出中,空單元格將保持空白,保留網格結構。
混合資料型別
IronXL自動處理不同的資料格式。 當您通過ToString()將數字作為字串傳遞時,Excel可能仍然根據值將其識別為數字。 為了精確的型別控制,在寫入之前將單元格值轉換為正確的型別:
if (cellValue is int intVal)
worksheet.SetCellValue(row + 1, col, intVal);
else if (cellValue is decimal decVal)
worksheet.SetCellValue(row + 1, col, (double)decVal);
else
worksheet.SetCellValue(row + 1, col, cellValue?.ToString() ?? string.Empty);If TypeOf cellValue Is Integer Then
Dim intVal As Integer = CType(cellValue, Integer)
worksheet.SetCellValue(row + 1, col, intVal)
ElseIf TypeOf cellValue Is Decimal Then
Dim decVal As Decimal = CType(cellValue, Decimal)
worksheet.SetCellValue(row + 1, col, CDbl(decVal))
Else
worksheet.SetCellValue(row + 1, col, If(cellValue?.ToString(), String.Empty))
End If這種方法保持了Excel中數字列的數字格式,因此公式和排序能夠在下游正確工作。
標題中的特殊字元
含有特殊字元例如>、和重音字母的欄位標題能正確匯出。 IronXL自動處理編碼,您無需進行任何轉義。
大型資料集
對於包含數以萬計行的網格,考慮將匯出邏輯移至後台執行緒以保持UI響應。將Task.Run調用中,並在完成回調時更新UI。 Microsoft關於使用任務的異步編程的文件詳細說明了這個模式。
對於其他如單元格樣式化、公式保存和密碼保護等場景,IronXL文件中詳細介紹了每一項。
主要匯出方法如何比較?
在承諾使用程式庫之前,了解最常見方法之間的取捨是有幫助的。
| 方法 | 需要Office | 欄位標題 | 性能 | 伺服器安全 |
|---|---|---|---|---|
| Microsoft Office Interop | 是 | 手動 | 緩慢 | 否 |
| OpenXml SDK | 否 | 手動 | 快速 | 是 |
| ClosedXML | 否 | 手動 | 好 | 是 |
| IronXL | 否 | 自動 | 快速 | 是 |
基於Interop的解決方案需要在伺服器上安裝Excel,即涉及許可證問題,也增加了部署的複雜性。 OpenXml SDK功能強大但屬於低階——編寫標題行需要手動構建XML結構。 IronXL和ClosedXML都提供了高階的API,但IronXL的WorkBook和WorkSheet模型緊密對應到開發人員已有的電子表格概念。
如何匯出為CSV而非XLSX?
當您需要一個CSV文件而不是Excel工作簿時,相同的匯出模式適用。 更改文件格式和副檔名:
WorkBook csvWorkbook = WorkBook.Create(ExcelFileFormat.CSV);
WorkSheet csvSheet = csvWorkbook.CreateWorkSheet("Data");
// Headers and data loops remain identical
using SaveFileDialog dialog = new SaveFileDialog
{
Filter = "CSV Files|*.csv",
FileName = "DataGridView_Export.csv"
};
if (dialog.ShowDialog() == DialogResult.OK)
csvWorkbook.SaveAs(dialog.FileName);Imports System.Windows.Forms
Dim csvWorkbook As WorkBook = WorkBook.Create(ExcelFileFormat.CSV)
Dim csvSheet As WorkSheet = csvWorkbook.CreateWorkSheet("Data")
' Headers and data loops remain identical
Using dialog As New SaveFileDialog With {
.Filter = "CSV Files|*.csv",
.FileName = "DataGridView_Export.csv"
}
If dialog.ShowDialog() = DialogResult.OK Then
csvWorkbook.SaveAs(dialog.FileName)
End If
End UsingCSV匯出在消費系統不支持XLSX或文件大小對於非常大的数据集是個問題時很有用。
如何在匯出的文件中樣式化標題行?
當標題行在視覺上有別於其他行時,匯出的資料更具可讀性。 IronXL提供單元格樣式選項,讓您可以在寫入標題值後應用粗體文字、背景顏色和字體大小:
// Write headers and apply bold styling
for (int col = 0; col < dataGridView1.Columns.Count; col++)
{
string cellAddress = worksheet.GetCellAddress(0, col);
worksheet[cellAddress].Value = dataGridView1.Columns[col].HeaderText;
worksheet[cellAddress].Style.Font.Bold = true;
worksheet[cellAddress].Style.SetBackgroundColor("#4472C4");
worksheet[cellAddress].Style.Font.FontColor = "#FFFFFF";
}' Write headers and apply bold styling
For col As Integer = 0 To dataGridView1.Columns.Count - 1
Dim cellAddress As String = worksheet.GetCellAddress(0, col)
worksheet(cellAddress).Value = dataGridView1.Columns(col).HeaderText
worksheet(cellAddress).Style.Font.Bold = True
worksheet(cellAddress).Style.SetBackgroundColor("#4472C4")
worksheet(cellAddress).Style.Font.FontColor = "#FFFFFF"
Next col一個樣式化的標題行,使匯出文件能夠立即用於報告,而不需要接收方手動進行格式化。 如需完整的樣式屬性列表,請參見IronXL cell styling reference。
如何開始免費試用?
IronXL提供免費試用,允許您測試所有功能,包括本文中顯示的匯出工作流程。 使用上面顯示的任何一個NuGet命令安裝包,在IronXL許可證頁面上生成試用金鑰,並在第一次調用程式庫之前在應用中設置它:
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";Imports IronXL
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"試用版將生成完整功能的Excel文件,並且不限制可用的功能。 對於生產部署,許可證選項涵蓋單一開發者、團隊和免版稅再分發。
對於相關的匯出場景,探索IronXL如何處理直接將DataTables匯出到Excel、將Excel文件讀取到DataGridViews中和從匯出的資料建立圖表。
為您的使用案例選擇正確的匯出策略
本教程中所示的簡單逐單元格匯出方法適用於大多數Windows Forms應用程式。 如果您的DataGridView綁定了一個DataTable,您也可以直接將DataTable傳遞給IronXL的DataTable到工作表轉換器,它會自動處理標題行。 選擇直接的DataTable方法,當您的列布局是固定的並且想要最短的程式碼路徑時。 選擇手動逐單元格方法,當您需要每個單元格的條件邏輯時——例如,突出顯示值低於可接受範圍的單元格,或在寫入之前明確映射可空型別。
對於伺服器端場景,例如產生可下載的Excel報告的ASP.NET Core控制器,相同的IronXL API適用。 唯一不同的是保存目標:而不是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet的內容型別將字節寫到HTTP響應中。 無論輸出是到文件還是到流,欄位標題傳輸方式相同。

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。
相關文章



