跳至页脚内容
使用 IRONXL

C# DataGridView 导出到 Excel:完整格式指南 | IronXL

C# DataGridView 导出到 Excel 并保留格式:完整指南:图 1 - C# DataGridView 导出到 Excel 并保留格式

DataGridView 数据导出到 Excel 文件是 Windows Forms 开发中最常见的任务之一。 在构建显示表格数据的业务应用程序(无论是销售报告、库存记录还是客户列表)时,用户希望点击一个按钮,就能收到一个格式正确的 Excel 文件,以便他们可以共享或进一步分析。 挑战在于如何干净利落地完成这项工作,既不依赖于在每个最终用户的计算机上安装 Microsoft Excel,也不与会泄漏内存或静默崩溃的 COM 互操作清理代码作斗争。 本指南将引导您完成使用IronXLDataGridView 导出到 Excel 的 C# 完整过程,涵盖从项目设置到高级单元格格式设置的所有步骤,最终生成可用于生产环境的代码。

立即开始使用 IronXL。
green arrow pointer

如何设置用于导出 DataGridView 的 Windows 窗体项目?

传统的导出数据的方法依赖于 Microsoft Interop——您需要打开"添加引用",导航到 COM 选项卡,选择 Microsoft Excel 对象库,并编写脆弱的代码来调用 Marshal.ReleaseComObject 以避免内存泄漏。 该模式要求在运行该应用程序的每台计算机上安装 Microsoft Excel,处理大型数据集时性能缓慢,并且在缺少 Office 许可证的部署环境中经常产生 COMException 错误。 微软自身关于 Office 自动化的指南明确建议在服务器端和自动化场景中使用第三方库。

IronXL移除了所有这些依赖项。 这是一个纯.NET库,无需 Microsoft Office 或任何 COM 注册即可读取和写入 .csv.ods 文件。 您可以通过NuGet安装它,然后立即开始编写代码。

通过NuGet安装IronXL

首先在 Visual Studio 中创建一个面向.NET 10 的新 Windows 窗体应用程序项目。向窗体表面添加一个 DataGridView 控件和一个 Button 控件。 将按钮命名为 btnExport,并为其添加标签"导出到 Excel"。 然后打开NuGet包管理器控制台并运行:

Install-Package IronXl.Excel
Install-Package IronXl.Excel
SHELL

在表单文件的顶部添加所需的命名空间:

using IronXL;
using System.Data;
using IronXL;
using System.Data;
$vbLabelText   $csharpLabel

这两个命名空间涵盖了读取和写入 Excel 工作簿所需的所有IronXL类型,以及用于处理连接您的 System.Data 对象和 DataTable 导出管道的标准 DataGridView 类型。

如何将示例数据加载到 DataGridView 控件中?

在构建导出逻辑之前,请用代表性数据填充您的 DataGridViewForm1_Load 事件是绑定 DataTable 作为数据源的正确位置。 在实际应用中,你会查询数据库或调用服务;这里硬编码的 DataTable 清楚地说明了结构。 Microsoft Docs 上的 DataGridView 控件概述提供了有关该控件如何管理数据源的更多上下文信息。

将 DataTable 绑定到 DataGridView

void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("ProductID", typeof(int));
    dt.Columns.Add("ProductName", typeof(string));
    dt.Columns.Add("Price", typeof(decimal));
    dt.Columns.Add("Stock", typeof(int));

    dt.Rows.Add(1, "Laptop", 999.99m, 50);
    dt.Rows.Add(2, "Mouse", 29.99m, 200);
    dt.Rows.Add(3, "Keyboard", 79.99m, 150);
    dt.Rows.Add(4, "Monitor", 349.99m, 75);
    dt.Rows.Add(5, "Webcam", 89.99m, 120);

    dataGridView1.DataSource = dt;
}
void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("ProductID", typeof(int));
    dt.Columns.Add("ProductName", typeof(string));
    dt.Columns.Add("Price", typeof(decimal));
    dt.Columns.Add("Stock", typeof(int));

    dt.Rows.Add(1, "Laptop", 999.99m, 50);
    dt.Rows.Add(2, "Mouse", 29.99m, 200);
    dt.Rows.Add(3, "Keyboard", 79.99m, 150);
    dt.Rows.Add(4, "Monitor", 349.99m, 75);
    dt.Rows.Add(5, "Webcam", 89.99m, 120);

    dataGridView1.DataSource = dt;
}
$vbLabelText   $csharpLabel

此代码使用顶级语句风格的事件处理程序签名。 DataTable 有四列类型化列——整数、字符串、十进制和整数IronXL在写入 Excel 工作簿时会保留这些列。 类型化的列很重要,因为IronXL将数值列写入数值单元格而不是文本,这使得用户可以在 Excel 中对值进行排序和求和,而无需重新格式化。

C# DataGridView 导出到 Excel 并设置格式:完整指南:图 2 - 表单的 UI

DataGridView 根据 DataTable 列名自动渲染列标题行。 导出时,您希望在 Excel 文件中保留标题行,这意味着您的导出代码必须将标题与数据行分开处理——下一节将详细介绍这一点。

对于生产环境,无论 DataTable 来自 Entity Framework、Dapper、 .NET还是任何其他数据访问层,都适用相同的模式。 DataGridView 绑定与导出代码解耦,因此您可以切换数据源而无需修改导出逻辑。

如何将DataGridView数据导出到Excel文件?

核心导出逻辑在按钮点击事件处理程序中运行。 IronXL在 LoadFromDataTable 上提供了一个 WorkSheet 方法,可以自动处理列到单元格的映射。 最简洁的方法是从 DataGridView 中提取 DataTable 并直接传递。 Open XML SDK 是 .xlsx 格式的基础,微软对此进行了文档说明,并证实了为什么像IronXL这样的纯.NET解决方案在程序化生成方面比 Interop 更胜一筹。

按钮点击导出处理程序

void btnExport_Click(object sender, EventArgs e)
{
    try
    {
        DataTable dt = new DataTable();

        foreach (DataGridViewColumn column in dataGridView1.Columns)
            dt.Columns.Add(column.HeaderText);

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) continue;

            DataRow dataRow = dt.NewRow();
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
                dataRow[i] = row.Cells[i].Value ?? DBNull.Value;

            dt.Rows.Add(dataRow);
        }

        WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
        WorkSheet worksheet = workbook.DefaultWorkSheet;
        worksheet.Name = "Product Data";

        worksheet.LoadFromDataTable(dt, true);

        string outputPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
            "DataGridViewExport.xlsx"
        );

        workbook.SaveAs(outputPath);
        MessageBox.Show($"Exported successfully to:\n{outputPath}", "Export Complete",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Export failed: {ex.Message}", "Error",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
void btnExport_Click(object sender, EventArgs e)
{
    try
    {
        DataTable dt = new DataTable();

        foreach (DataGridViewColumn column in dataGridView1.Columns)
            dt.Columns.Add(column.HeaderText);

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) continue;

            DataRow dataRow = dt.NewRow();
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
                dataRow[i] = row.Cells[i].Value ?? DBNull.Value;

            dt.Rows.Add(dataRow);
        }

        WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
        WorkSheet worksheet = workbook.DefaultWorkSheet;
        worksheet.Name = "Product Data";

        worksheet.LoadFromDataTable(dt, true);

        string outputPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
            "DataGridViewExport.xlsx"
        );

        workbook.SaveAs(outputPath);
        MessageBox.Show($"Exported successfully to:\n{outputPath}", "Export Complete",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Export failed: {ex.Message}", "Error",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
$vbLabelText   $csharpLabel

C# DataGridView 导出到 Excel 并保留格式:完整指南:图 3 - 生成的 Excel 文件

LoadFromDataTable(dt, true) 调用接受 DataTable 和一个布尔标志,该标志告诉IronXL将列名写入 Excel 的第一行——这些列名将成为你的标题单元格。 工作簿使用 Environment.SpecialFolder.Desktop 而不是硬编码路径保存到用户的桌面,这使得代码可以在用户帐户之间移植。

null 检查(?? 当单元格不包含值时,会抛出 DBNull.Value) prevents a NullReferenceException 异常。 这对于现实世界的数据来说很重要,因为可选字段可能为空。 IronXL将DBNull` 写入空单元格,而不是字符串"DBNull",因此输出保持干净。

有关将数据从 Excel 文件读回 DataGridView 的更多详细信息,请参阅IronXL DataTable 文档,其中涵盖了反向操作以及如何将 Excel 转换为多工作表工作簿的 DataSet

如何将专业格式应用于导出的Excel文件?

Excel 文件中的纯数据虽然功能齐全,但专业格式的输出(粗体标题、与内容相匹配的列宽、交替的行背景颜色)决定了用户信任的工具和他们导出后立即手动重新格式化的工具之间的区别。 IronXL公开了丰富的单元格样式 API ,涵盖字体、颜色、边框、数字格式和对齐方式。 OOXML 电子表格样式规范定义了IronXL写入的底层格式,让您确信输出可以在任何兼容的应用程序中正确打开。

应用标题样式和交替行颜色

void ExportWithFormatting(object sender, EventArgs e)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;
    worksheet.Name = "Formatted Export";

    string[] headers = { "ID", "Product Name", "Price", "Stock" };

    // Write and style header row
    for (int col = 0; col < headers.Length; col++)
    {
        char colLetter = (char)('A' + col);
        string cellAddress = $"{colLetter}1";

        worksheet.SetCellValue(0, col, headers[col]);
        worksheet[cellAddress].Style.Font.Bold = true;
        worksheet[cellAddress].Style.Font.Height = 12;
        worksheet[cellAddress].Style.SetBackgroundColor("#4472C4");
        worksheet[cellAddress].Style.Font.Color = "#FFFFFF";
        worksheet[cellAddress].Style.HorizontalAlignment =
            IronXl.Styles.HorizontalAlignment.Center;
    }

    // Write data rows with alternating background colors
    int rowIndex = 1;
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.IsNewRow) continue;

        for (int col = 0; col < dataGridView1.Columns.Count; col++)
        {
            worksheet.SetCellValue(rowIndex, col,
                row.Cells[col].Value?.ToString() ?? string.Empty);
        }

        if (rowIndex % 2 == 0)
        {
            string rangeAddress = $"A{rowIndex + 1}:D{rowIndex + 1}";
            worksheet[rangeAddress].Style.SetBackgroundColor("#D6DCE5");
        }

        rowIndex++;
    }

    // Format the Price column as currency
    worksheet["C2:C100"].Style.Format = "$#,##0.00";

    // Auto-fit column widths
    worksheet.AutoSizeColumn(0);
    worksheet.AutoSizeColumn(1);
    worksheet.AutoSizeColumn(2);
    worksheet.AutoSizeColumn(3);

    string outputPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "FormattedExport.xlsx"
    );

    workbook.SaveAs(outputPath);
    MessageBox.Show("Formatted export complete.", "Done",
        MessageBoxButtons.OK, MessageBoxIcon.Information);
}
void ExportWithFormatting(object sender, EventArgs e)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;
    worksheet.Name = "Formatted Export";

    string[] headers = { "ID", "Product Name", "Price", "Stock" };

    // Write and style header row
    for (int col = 0; col < headers.Length; col++)
    {
        char colLetter = (char)('A' + col);
        string cellAddress = $"{colLetter}1";

        worksheet.SetCellValue(0, col, headers[col]);
        worksheet[cellAddress].Style.Font.Bold = true;
        worksheet[cellAddress].Style.Font.Height = 12;
        worksheet[cellAddress].Style.SetBackgroundColor("#4472C4");
        worksheet[cellAddress].Style.Font.Color = "#FFFFFF";
        worksheet[cellAddress].Style.HorizontalAlignment =
            IronXl.Styles.HorizontalAlignment.Center;
    }

    // Write data rows with alternating background colors
    int rowIndex = 1;
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.IsNewRow) continue;

        for (int col = 0; col < dataGridView1.Columns.Count; col++)
        {
            worksheet.SetCellValue(rowIndex, col,
                row.Cells[col].Value?.ToString() ?? string.Empty);
        }

        if (rowIndex % 2 == 0)
        {
            string rangeAddress = $"A{rowIndex + 1}:D{rowIndex + 1}";
            worksheet[rangeAddress].Style.SetBackgroundColor("#D6DCE5");
        }

        rowIndex++;
    }

    // Format the Price column as currency
    worksheet["C2:C100"].Style.Format = "$#,##0.00";

    // Auto-fit column widths
    worksheet.AutoSizeColumn(0);
    worksheet.AutoSizeColumn(1);
    worksheet.AutoSizeColumn(2);
    worksheet.AutoSizeColumn(3);

    string outputPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "FormattedExport.xlsx"
    );

    workbook.SaveAs(outputPath);
    MessageBox.Show("Formatted export complete.", "Done",
        MessageBoxButtons.OK, MessageBoxIcon.Information);
}
$vbLabelText   $csharpLabel

C# DataGridView 导出到 Excel 并设置格式:完整指南:图 4 - 生成的格式化 Excel 文件的输出

格式化代码应用了多种技术。 标题行采用蓝色背景(#4472C4),白色文本,12 号粗体字体,居中对齐——这是标准的商务电子表格样式。 数据行每隔偶数行交替显示白色和浅灰色(#D6DCE5),这样用户更容易在宽表格中阅读而不会丢失位置。 "价格"列使用 Excel 内置的货币格式 ($#,##0.00),因此电子表格中的值会以美元符号和两位小数显示,而不会更改底层数值数据。 AutoSizeColumn 将每一列调整到其最长值,因此不会截断任何内容。

您可以使用单元格边框样式条件格式数据验证规则进一步扩展此模式。 对于必须符合公司模板的报告,您还可以设置页面布局和打印区域,以便导出的文件无需调整即可打印。

如何处理大型数据集和性能调优?

DataGridView 绑定到数千行时,逐个单元格迭代会变得明显变慢。 两项优化措施显著提升了性能。 首先,使用 LoadFromDataTable 而不是每个单元格的 SetCellValue 调用。 其次,如果您的数据源是 DataTable,请直接将其传递给IronXL,而不是通过 DataGridView 行提取值:

void ExportLargeDataset(DataTable sourceTable)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;

    // Direct DataTable load -- fastest path for large data
    worksheet.LoadFromDataTable(sourceTable, true);

    // Apply header styling after load
    int colCount = sourceTable.Columns.Count;
    for (int col = 0; col < colCount; col++)
    {
        char colLetter = (char)('A' + col);
        worksheet[$"{colLetter}1"].Style.Font.Bold = true;
        worksheet[$"{colLetter}1"].Style.SetBackgroundColor("#4472C4");
        worksheet[$"{colLetter}1"].Style.Font.Color = "#FFFFFF";
    }

    workbook.SaveAs(Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "LargeExport.xlsx"
    ));
}
void ExportLargeDataset(DataTable sourceTable)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;

    // Direct DataTable load -- fastest path for large data
    worksheet.LoadFromDataTable(sourceTable, true);

    // Apply header styling after load
    int colCount = sourceTable.Columns.Count;
    for (int col = 0; col < colCount; col++)
    {
        char colLetter = (char)('A' + col);
        worksheet[$"{colLetter}1"].Style.Font.Bold = true;
        worksheet[$"{colLetter}1"].Style.SetBackgroundColor("#4472C4");
        worksheet[$"{colLetter}1"].Style.Font.Color = "#FFFFFF";
    }

    workbook.SaveAs(Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "LargeExport.xlsx"
    ));
}
$vbLabelText   $csharpLabel

对于超过 10,000 行的数据集,在后台线程上运行导出操作可以保持 UI 的响应性。将导出逻辑包装在 Task.Run 中,并使用 InvokeMessageBox.Show 回调序列化到 UI 线程。 IronXL对独立实例上的写入操作是线程安全的,因此如果需要,您可以同时运行多个导出操作。

其他性能资源: Excel导出性能指南 -处理大型 Excel 文件 -流式 Excel 输出

IronXL与 Microsoft Interop 在 DataGridView 导出方面有何区别?

许多开发人员首先选择 Microsoft Excel Interop,因为它随 Office 一起提供,无需其他软件包。 然而,互操作性会带来实际成本,这些成本会在生产环境中迅速显现出来。 下表总结了主要区别:

IronXL与 Microsoft Excel Interop 在 DataGridView 导出方面的比较
能力 IronXL Microsoft Interop
需要安装 Microsoft Excel
可在服务器/云环境中运行 否(微软不支持)
需要清理 COM 对象 是的(Marshal.ReleaseComObject)
处理大型数据集的性能 快速(纯.NET) 速度慢(COM编组开销)
安装方法 NuGet COM 参考/Office 安装
支持的.NET版本 .NET 4.6.2 -- .NET 10 仅限.NET Framework (功能有限)
XLSX、CSV、ODS 支持 仅可通过 Excel 传输 XLSX/XLS 格式文件

微软自己的文档警告不要在服务器或服务帐户中使用 Office Interop,理由是稳定性和许可方面存在问题。 IronXL可以在 Azure 应用服务、Windows 服务主机、Docker 容器以及任何其他无法运行 Excel 等桌面应用程序的无头环境中正常工作。

对于已经使用 Interop 并希望迁移的团队来说,IronXL 的 API 映射非常接近,大多数 WorkBookWorkSheet 操作可以直接转换。 IronXL迁移指南涵盖了常见的互操作模式及其IronXL等效模式。

下一步计划是什么?

使用IronXL将 DataGridView 数据导出到 Excel 只需要安装NuGet包和几行代码,即可用一个干净、可维护的解决方案取代脆弱的 COM 互操作方法,该解决方案可在任何部署环境中运行。 这里介绍的技术——基本导出、格式化输出、大数据集优化和比较表——为您提供了在生产 Windows Forms 应用程序中发布此功能所需的一切。

接下来,您可以探索以下相关功能:

-使用 C# 从头开始​​创建 Excel 文件——无需数据源即可通过编程方式构建工作簿 -将 Excel 文件读取到数据表中——这是将 Excel 数据导入回应用程序的逆操作。 -应用条件格式——根据单元格的值自动突出显示单元格 -在 Excel 中设置图表数据——将图表嵌入导出的工作簿中 -对 Excel 文件进行密码保护——在分发之前确保导出报告的安全。 -导出为 CSV 格式-- 当收件人需要平面文件格式而不是 .xlsx

您可以开始免费试用IronXL,在您的项目中测试其全部功能集,或者在准备好进行生产部署时查看IronXL许可选项

常见问题解答

如何在 C# 中将 DataGridView 数据导出到 Excel?

通过NuGet安装IronXL ,从 DataGridView 中提取 DataTable,创建 WorkBook 和 WorkSheet,调用 worksheet.LoadFromDataTable(dt, true),然后使用 workbook.SaveAs 保存。

将 DataGridView 导出到 Excel 时有哪些格式选项?

IronXL支持粗体字体、背景颜色、字体颜色、水平对齐、数字格式(如货币)、自动调整列宽、边框样式和条件格式。

导出DataGridView数据是否需要安装Microsoft Excel?

不IronXL是一个纯.NET库,它生成 Excel 文件不需要 Microsoft Office 或在计算机上进行任何 COM 注册。

在将 DataGridView 导出到 Excel 时,能否设置标题样式?

是的。写入标题行后,通过地址访问每个标题单元格,并设置 Style.Font.Bold、Style.SetBackgroundColor 和 Style.Font.Color 属性。

从 DataGridView 导出时,如何在 Excel 中应用交替行颜色?

在遍历 DataGridView 行时跟踪行索引,对于偶数行,使用 worksheet[rangeAddress].Style.SetBackgroundColor 和您选择的十六进制颜色应用范围样式。

将 DataGridView 导出到 Excel 时,如何处理大型数据集?

直接将底层 DataTable 传递给 worksheet.LoadFromDataTable,而不是逐个遍历单元格。对于非常大的数据集,请使用 Task.Run 在后台线程中运行导出操作。

IronXL与 Microsoft Excel Interop 在 DataGridView 导出方面有何不同?

IronXL不需要 Microsoft Excel,可在服务器和云环境中运行,无需 COM 清理代码,并且在处理大型数据集时性能显著提高。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me