使用 IRONXL C# 将 DataGridView 导出到 Excel 并带列标题 Curtis Chau 已更新:2026年3月1日 下载 IronXL NuGet 下载 DLL 下载 免费试用 LLM副本 LLM副本 将页面复制为 Markdown 格式,用于 LLMs 在 ChatGPT 中打开 向 ChatGPT 咨询此页面 在双子座打开 向 Gemini 询问此页面 在 Grok 中打开 向 Grok 询问此页面 打开困惑 向 Perplexity 询问有关此页面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 复制链接 电子邮件文章 如何在 C# 中将带有列标题的 DataGridView 导出到 Excel? 将 Windows Forms DataGridView 控件中的数据导出为 Excel 格式是一个常见的需求,但开发人员经常会遇到一个令人沮丧的问题:导出的文件缺少列标题。 当您需要将 DataGridView 导出到 Excel 并保留列标题时,解决方案必须能够可靠地保留所有数据和格式。 使用 Microsoft Office Interop 的传统方法可能速度慢、不稳定,并且需要在运行代码的每台计算机上安装 MS Excel。 IronXL可以完美地解决这个问题。 这是一个.NET Excel 库,可以读取、创建和写入 Excel 文件,而无需任何 Office 依赖项。 本教程将引导您完成一个完整的导出解决方案——只需几行代码即可处理列标题、数据类型、空单元格和用户友好的文件保存。 最后,您将拥有一个可用的 Windows Forms 按钮处理程序,该处理程序可以将 DataGridView 导出到 XLSX 文件,并保留所有列标题。 开始之前你需要准备什么 在编写任何代码之前,请确保以下事项已就绪: Visual Studio 2022 或更高版本(任何版本) 已安装.NET 10 SDK 一个面向.NET 10 的 Windows 窗体应用程序项目 -NuGet访问来安装IronXL 以下示例通篇使用顶级语句和现代.NET 10 项目结构。 如何在.NET项目中安装库? 在 Visual Studio 中打开NuGet程序包管理器控制台,并运行以下任一命令。 该软件包已在NuGet Gallery上列出,面向.NET Standard 2.0 及更高版本,因此可与任何现代.NET项目配合使用。 Install-Package IronXL Install-Package IronXL SHELL dotnet add package IronXL dotnet add package IronXL SHELL 安装完成后,请在表单文件顶部添加所需的命名空间: using IronXL; using System; using System.Data; using System.Windows.Forms; using IronXL; using System; using System.Data; using System.Windows.Forms; $vbLabelText $csharpLabel 这些导入功能可以访问IronXL 的 Excel 功能、数据表操作以及导出过程所需的 Windows 窗体控件。 如何使用示例数据设置 DataGridView? 首先在 Visual Studio 中创建一个 Windows 窗体应用程序。 通过设计器向主窗体添加名为 dataGridView1 的 DataGridView 和名为 btnExport 的 Button。 然后在表单加载时填充表格: 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; } } 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; } } $vbLabelText $csharpLabel 在 dt.Columns.Add(...) 调用中定义的列名将成为导出 Excel 文件中的标题行。您可以替换此处的任何数据源——数据库查询结果、CSV 导入或存储为 DataTable 的 API 响应,所有这些都与后面所示的导出代码的工作方式相同。 DataTable 方法特别方便,因为 DataGridView 公开了一个 DataSource 属性,该属性接受任何 IList 或 IBindingList,这意味着相同的导出代码无需修改即可推广到每个绑定场景。 如果您的 DataGridView 是通过 SqlDataAdapter 从数据库填充的,则 DataTable 已经包含类型化的列。 将这些键入的值传递给 SetCellValue 而不是对它们调用 ToString(),可以使 Excel 输出中的数值列保持为数值,这对于任何下游报告或数据透视表的使用都很重要。 这将创建一个包含所有数据的 DataGridView: 对于更高级的数据绑定场景,微软关于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 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); } } $vbLabelText $csharpLabel 分解导出步骤 该方法的每个步骤都有其特定目的: 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 (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); $vbLabelText $csharpLabel 这种方法可以保持 Excel 中的数值列为数值型,以便后续的公式和排序功能能够正常工作。 标题中的特殊字符 包含特殊字符(例如 >)和带重音符号的字母的列标题可以正确导出。 IronXL会自动处理编码,无需您进行任何转义操作。 大型数据集 对于包含数万行的表格,请考虑将导出逻辑移至后台线程以保持 UI 的响应速度。将 WorkBook.Create 和循环逻辑封装在一个 Task.Run 调用中,并在回调完成后更新 UI。 微软关于 使用 Task 进行异步编程的文档详细解释了这种模式。 对于单元格样式、公式保留和密码保护等其他场景, IronXL文档对每一种场景都有详细介绍。 主要出口方式有何异同? 在决定使用某个库之前,了解最常用方法之间的优缺点会很有帮助。 C# 中 DataGridView 与 Excel 导出方法的比较 方法 办公室要求 列标题 表现 服务器安全 Microsoft Office Interop 是 手册 慢的 无 OpenXml SDK 无 手册 快速地 是 ClosedXML 无 手册 好的 是 IronXL 无 自动翻译 快速地 是 基于互操作性的解决方案需要在服务器上安装 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); 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); $vbLabelText $csharpLabel 当使用系统不支持 XLSX 格式,或者对于非常大的数据集来说文件大小是一个问题时,CSV 导出非常有用。 如何在导出的文件中设置标题行的样式? 导出的数据如果标题行在视觉上清晰可见,则更易于阅读。 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 (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"; } $vbLabelText $csharpLabel 带有样式的标题行使导出的文件可以直接用于报告,而无需收件人手动应用格式。 有关样式属性的完整列表,请参阅IronXL单元格样式参考。 如何开始免费试用? IronXL提供免费试用版,让您可以测试所有功能,包括本文中所示的导出工作流程。 使用上面显示的任一NuGet命令安装该软件包,在IronXL许可页面上生成试用密钥,并在首次调用库之前将其设置到您的应用程序中: IronXl.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"; IronXl.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"; $vbLabelText $csharpLabel 该试用版会生成功能齐全的 Excel 文件,并且不会限制哪些功能可用。 对于生产部署,许可选项涵盖单个开发人员、团队和免版税再分发。 对于相关的导出场景,请探索IronXL如何处理将 DataTables 直接导出到 Excel 、将 Excel 文件读取到 DataGridViews以及从导出的数据创建图表。 为您的用例选择合适的出口策略 本教程中展示的逐单元格导出方法简单直接,适用于大多数 Windows Forms 应用程序。 如果您的 DataGridView 绑定到 DataTable,您还可以将 DataTable 直接传递给 IronXL 的DataTable 到工作表转换器,该转换器会自动处理标题行。 如果列布局固定,并且您希望代码路径最短,请选择直接使用 DataTable 的方法。 当您需要对每个单元格应用条件逻辑时,请选择逐单元格手动操作的方法——例如,突出显示值超出可接受范围的单元格,或者在写入之前显式映射可空类型。 对于生成可下载 Excel 报表的服务器端场景(例如ASP.NET Core控制器),同样的IronXL API 也适用。 唯一的区别在于保存目标:不是调用 SaveAs(filePath),而是调用 workbook.ToByteArray(),并将字节写入内容类型为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 的 HTTP 响应。 无论输出到文件还是流,列标题的传输方式都完全相同。 常见问题解答 如何在 C# 中将 DataGridView 数据导出到 Excel? 使用IronXL库创建一个 Excel 工作簿,遍历 DataGridView 列,将标题写入第 0 行,然后遍历数据行,从第 1 行开始写入单元格值。使用 SaveAs 保存工作簿。 使用 IronXL 导出数据有什么好处? IronXL提供了一个用于 Excel 操作的高级 API,无需安装 Microsoft Office。它能够处理标题、数据类型和文件格式,无需手动操作 XML。 从 DataGridView 导出到 Excel 时能否保留列标题? 是的。在写入任何数据行之前,请读取每个 DataGridView 列的 HeaderText 属性,并将其写入IronXL工作表的第 0 行。 开始使用 IronXL 导出到 Excel 是否需要试用版? 我们提供免费试用版,试用版可访问所有功能。请安装NuGet包,生成试用密钥,并在调用任何库之前设置IronXL。 IronXl.Excel 能否在导出到 Excel 时处理大型 DataGridView 数据集? 是的。对于非常大的网格,可以使用 Task.Run 在后台线程中运行导出操作,以在IronXL写入数据时保持 UI 的响应性。 使用 IronXl.Excel 将 DataGridView 导出到 Excel 的步骤是什么? 安装IronXL,创建一个 WorkBook 和 WorkSheet,遍历 DataGridView 列以在第 0 行写入标题,遍历行以从第 1 行开始写入数据,然后调用 SaveAs 保存文件。 为什么选择 IronXL 而不是其他导出到 Excel 的库? IronXL无需安装 Office,可在服务器上运行,并提供简洁的工作簿/工作表 API,自然地与开发人员对电子表格的思考方式相匹配——并具有强大的文档和积极的支持。 IronXL 是否提供故障排除支持? 是的。IronXL 为授权客户提供详细的 API 文档、代码示例和直接的工程支持。 IronXl.Excel 能否自定义 Excel 导出过程? 是的。写入数据后,您可以使用 IronXL 的样式 API 对任何单元格区域应用粗体字体、背景颜色、边框和数字格式。 IronXL 是否支持将数据导出为 Excel 以外的其他格式? 是的。IronXL 支持 XLSX、XLS、CSV 和 TSV 格式。IronXL格式只需更改传递给 WorkBook.Create 的 ExcelFileFormat 枚举值即可。 Curtis Chau 立即与工程团队聊天 技术作家 Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。 相关文章 已更新2026年3月1日 在.NET C# 中下载 Excel 文件:将数据导出为 XLSX、CSV 等格式 使用 C# 和IronXL在ASP.NET Core中下载 Excel 文件。从 MVC 控制器导出数据到 XLSX、CSV 和 XML 格式,并返回 MemoryStream 和 File() 函数。包含代码示例。 阅读更多 已更新2026年3月1日 如何在Blazor中使用IronXL导出 Excel 文件 学习如何使用IronXL在Blazor Server 应用程序中将数据导出到 Excel。本指南涵盖项目设置、服务设计、条件格式设置、多工作表报表和错误处理,并提供完整的 C# 代码示例。 阅读更多 已更新2026年2月27日 如何在 C# 中读取 Excel 文件而不是使用 StreamReader 了解为什么 StreamReader 无法读取 Excel 文件,以及如何在 C# .NET中使用IronXL从磁盘或内存流加载 XLSX 和 XLS 工作簿。 阅读更多 如何使用IronXL在 C# 中快速读取 CSV 文件?ExcelDataReader 写 Excel 文件:...
已更新2026年3月1日 在.NET C# 中下载 Excel 文件:将数据导出为 XLSX、CSV 等格式 使用 C# 和IronXL在ASP.NET Core中下载 Excel 文件。从 MVC 控制器导出数据到 XLSX、CSV 和 XML 格式,并返回 MemoryStream 和 File() 函数。包含代码示例。 阅读更多
已更新2026年3月1日 如何在Blazor中使用IronXL导出 Excel 文件 学习如何使用IronXL在Blazor Server 应用程序中将数据导出到 Excel。本指南涵盖项目设置、服务设计、条件格式设置、多工作表报表和错误处理,并提供完整的 C# 代码示例。 阅读更多
已更新2026年2月27日 如何在 C# 中读取 Excel 文件而不是使用 StreamReader 了解为什么 StreamReader 无法读取 Excel 文件,以及如何在 C# .NET中使用IronXL从磁盘或内存流加载 XLSX 和 XLS 工作簿。 阅读更多