跳至页脚内容
使用 IRONXL

如何使用IronXL从 C# 中的 GridView 导出到 Excel

将 GridView 数据导出到真正的 Excel 文件是ASP.NET Web 应用程序中最常见的需求之一。 使用 HtmlTextWriterStringWriter 的传统方法会创建虚假的 Excel 文件,当用户尝试打开这些文件时,会触发浏览器警告和格式错误。 本指南向您展示如何使用IronXL将 GridView 数据导出到格式正确的 .xlsx 文件,从而消除开发人员在使用传统方法时遇到的难题。

为什么传统的 GridView 导出方法会导致问题?

在ASP.NET C# 中,从 GridView 导出到 Excel 的经典方法涉及渲染 HTML 并设置带有附件文件名值的 Response 标头。 这种方法需要重写 public override void VerifyRenderingInServerForm 以避免运行时错误。 生成的文件不是真正的 Excel 文件,而是带有 .xls 扩展名的 HTML 文件,导致 Excel 在用户打开它时显示警告消息。

具体而言,传统技术存在以下缺点:

  • Excel 每次打开文件时都会显示"文件格式和扩展名不匹配"的警告 由于数据以原始 HTML 格式存储,因此格式和数据类型会丢失。
  • 您必须使用 VerifyRenderingInServerForm 作为变通方案,但这会给您的项目增加技术债务。 生成的文件缺少正确的单元格元数据,因此无法用于下游自动化或报告工具。

IronXL通过创建真正的 .xlsx Excel 文件来解决这些问题,而无需在服务器上安装 Microsoft Office。 您可以获得一个任何电子表格应用程序都能干净利落地打开的文件,其中保留了正确的数据类型、样式和 OOXML 结构。

如何在ASP.NET项目中安装IronXL ?

在编写任何导出逻辑之前,请使用NuGet包管理器将IronXL添加到您的项目中。 在 Visual Studio 中打开软件包管理器控制台并运行:

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

或者,在NuGet程序包管理器 UI 中搜索 IronXl.Excel,然后从那里安装。 安装完成后,您可以在任何代码隐藏文件中引用 IronXL 命名空间。

IronXL 的目标平台是.NET Standard 2.0 及更高版本,因此它既适用于现代ASP.NET Core项目,也适用于经典的ASP.NET Framework 应用程序。 您的 Web 服务器无需 COM 互操作、无需安装 Office,也无需其他任何本地依赖项。

更多详情请参阅IronXL安装指南IronXL NuGet包页面

如何设置ASP.NET GridView 以进行导出?

创建您的 Default.aspx 页面,其中包含 GridView 控件和导出按钮。 标记语言为标准 Web 表单:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewExportTest.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>Export GridView to Excel</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <h2>IronXL GridView Export Demo</h2>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true"
                HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" CellPadding="5">
            </asp:GridView>
            <br />
            <asp:Button ID="btnExport" runat="server" Text="Export to Excel (.xlsx)"
                OnClick="btnExport_Click" />
        </div>
    </form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewExportTest.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>Export GridView to Excel</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <h2>IronXL GridView Export Demo</h2>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true"
                HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" CellPadding="5">
            </asp:GridView>
            <br />
            <asp:Button ID="btnExport" runat="server" Text="Export to Excel (.xlsx)"
                OnClick="btnExport_Click" />
        </div>
    </form>
</body>
</html>
$vbLabelText   $csharpLabel

此标记创建了一个简单的页面,其中包含绑定的 GridView 和一个触发导出的按钮。 AutoGenerateColumns="true" 属性表示网格直接从绑定的 DataTable 读取列名。

将示例数据绑定到 GridView

在您的代码隐藏文件中,将 DataTable 绑定到网格,并将其存储在 Session 中,以便在导出回发期间稍后使用:

using System;
using System.Data;
using System.Web.UI;
using IronXL;

namespace GridViewExport
{
    public partial class Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BindGridView();
            }
        }

        private void BindGridView()
        {
            DataTable dt = new DataTable("Employees");
            dt.Columns.Add("EmployeeID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Department", typeof(string));
            dt.Columns.Add("Salary", typeof(decimal));

            dt.Rows.Add(1, "John Smith", "Engineering", 75000);
            dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
            dt.Rows.Add(3, "Mike Wilson", "Sales", 70000);
            dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

            GridView1.DataSource = dt;
            GridView1.DataBind();

            // Store DataTable in Session for export postback
            Session["GridData"] = dt;
        }
    }
}
using System;
using System.Data;
using System.Web.UI;
using IronXL;

namespace GridViewExport
{
    public partial class Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BindGridView();
            }
        }

        private void BindGridView()
        {
            DataTable dt = new DataTable("Employees");
            dt.Columns.Add("EmployeeID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Department", typeof(string));
            dt.Columns.Add("Salary", typeof(decimal));

            dt.Rows.Add(1, "John Smith", "Engineering", 75000);
            dt.Rows.Add(2, "Sarah Johnson", "Marketing", 65000);
            dt.Rows.Add(3, "Mike Wilson", "Sales", 70000);
            dt.Rows.Add(4, "Emily Davis", "Engineering", 80000);

            GridView1.DataSource = dt;
            GridView1.DataBind();

            // Store DataTable in Session for export postback
            Session["GridData"] = dt;
        }
    }
}
$vbLabelText   $csharpLabel

DataTable 存储在 Session 中,可以避免在导出按钮触发的回发期间重新查询数据库或重建数据。 对于实际应用,请使用Entity Framework.NET进行数据库查询,替换硬编码的行。

在.NET C# 中从 GridView 导出到 Excel:一个简洁的 C# 解决方案:图 1 - 显示示例 GridView 数据的 UI

如何使用IronXL将 GridView 数据导出到 Excel?

GridView 导出的简洁方法会将您的 DataTable 转换为IronXL WorkBook,并将结果直接流式传输到浏览器。 以下是完整的导出方法:

protected void btnExport_Click(object sender, EventArgs e)
{
    ExportGridViewToExcel();
}

private void ExportGridViewToExcel()
{
    DataTable dt = (DataTable)Session["GridData"];

    // Create a workbook and load data from the DataTable
    WorkBook workbook = WorkBook.Create();
    WorkBook.LoadWorkSheetsFromDataSet(new DataSet { Tables = { dt } }, workbook);
    WorkSheet worksheet = workbook.DefaultWorkSheet;

    // Apply header row formatting
    var headerRange = worksheet["A1:D1"];
    headerRange.Style.Font.Bold = true;
    headerRange.Style.Font.Size = 12;
    headerRange.Style.SetBackgroundColor("#3AC0F2");

    // Stream the file to the browser
    string filename = "GridViewExport_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";
    Response.Clear();
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("content-disposition", "attachment;filename=" + filename);
    workbook.SaveAsStream(Response.OutputStream, IronXl.Enum.FileFormat.Xlsx);
    Response.Flush();
    Response.End();
}
protected void btnExport_Click(object sender, EventArgs e)
{
    ExportGridViewToExcel();
}

private void ExportGridViewToExcel()
{
    DataTable dt = (DataTable)Session["GridData"];

    // Create a workbook and load data from the DataTable
    WorkBook workbook = WorkBook.Create();
    WorkBook.LoadWorkSheetsFromDataSet(new DataSet { Tables = { dt } }, workbook);
    WorkSheet worksheet = workbook.DefaultWorkSheet;

    // Apply header row formatting
    var headerRange = worksheet["A1:D1"];
    headerRange.Style.Font.Bold = true;
    headerRange.Style.Font.Size = 12;
    headerRange.Style.SetBackgroundColor("#3AC0F2");

    // Stream the file to the browser
    string filename = "GridViewExport_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx";
    Response.Clear();
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("content-disposition", "attachment;filename=" + filename);
    workbook.SaveAsStream(Response.OutputStream, IronXl.Enum.FileFormat.Xlsx);
    Response.Flush();
    Response.End();
}
$vbLabelText   $csharpLabel

导出流程详解

该过程可分解为三个逻辑步骤:

1.检索数据表-- Session["GridData"] 返回与绑定到网格相同的 DataTable。 这样可以避免重复的数据库调用。 2.构建工作簿-- WorkBook.LoadWorkSheetsFromDataSet 会自动为每个 DataTableDataSet 创建一个工作表,并将列标题和行值复制到相应的单元格中。 3.流式传输到浏览器-- 将 Content-Type 设置为 OOXML MIME 类型并写入 Response.OutputStream 会触发浏览器下载,并带有正确的 .xlsx 扩展名。 不会向磁盘写入临时文件。

这与传统的 HtmlTextWriter 方法有着根本的不同。 导出的文件使用 Open XML 格式——与 Microsoft Excel 原生使用的格式相同——因此打开时不会出现警告。

有关以编程方式加载数据的更多信息,请参阅IronXL WorkBook 文档以及如何在 C# 中将 DataTable 导出到 Excel

在.NET C# 中从 GridView 导出到 Excel:一个简洁的 C# 解决方案:图 2 - 导出的 Excel 文件

如何将 Excel 文件保存到磁盘而不是进行流式传输?

如果您的应用程序需要在向用户提供下载链接之前将导出内容存档到服务器,请将工作簿保存到文件路径,而不是将其流式传输到 Response.OutputStream:

private void SaveExcelToDisk(WorkBook workbook, string exportFolder)
{
    // Ensure the exports directory exists
    if (!System.IO.Directory.Exists(exportFolder))
    {
        System.IO.Directory.CreateDirectory(exportFolder);
    }

    string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
    string filename = System.IO.Path.Combine(exportFolder, $"Report_{timestamp}.xlsx");

    workbook.SaveAs(filename);

    // Return the relative path for generating a download link
    string relativePath = "~/Exports/Report_" + timestamp + ".xlsx";
    Response.Write($"<script>alert('File saved to {relativePath}');</script>");
}
private void SaveExcelToDisk(WorkBook workbook, string exportFolder)
{
    // Ensure the exports directory exists
    if (!System.IO.Directory.Exists(exportFolder))
    {
        System.IO.Directory.CreateDirectory(exportFolder);
    }

    string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
    string filename = System.IO.Path.Combine(exportFolder, $"Report_{timestamp}.xlsx");

    workbook.SaveAs(filename);

    // Return the relative path for generating a download link
    string relativePath = "~/Exports/Report_" + timestamp + ".xlsx";
    Response.Write($"<script>alert('File saved to {relativePath}');</script>");
}
$vbLabelText   $csharpLabel

选择流媒体播放还是磁盘保存

流式导出策略与磁盘保存导出策略的比较
战略 优点 缺点 最适合
流式传输到浏览器 不占用磁盘空间,立即交付 无法存档或重新发送 按需用户导出
保存到磁盘 文件将保留以供审核、重新下载或通过电子邮件发送。 需要进行清理工作和磁盘空间管理。 定期报告、审计跟踪

对于大多数交互式 Web 应用程序而言,直接流式传输到浏览器是最佳选择。只有在需要通过电子邮件发送文件、出于合规性要求存储文件或允许用户从文件管理页面重新下载文件时,才需要将其保存到磁盘。

如何对导出的Excel表格应用高级格式?

IronXL可让您对单元格样式、列宽、数字格式等进行精细控制。 以下示例展示了如何构建专业风格的导出文件:

private void ExportWithFormatting()
{
    DataTable dt = new DataTable("Products");
    dt.Columns.Add("Product", typeof(string));
    dt.Columns.Add("Category", typeof(string));
    dt.Columns.Add("Price", typeof(decimal));
    dt.Columns.Add("InStock", typeof(bool));

    dt.Rows.Add("Widget A", "Hardware", 29.99m, true);
    dt.Rows.Add("Widget B", "Hardware", 49.99m, false);
    dt.Rows.Add("Service Plan", "Support", 199.00m, true);

    WorkBook workbook = WorkBook.Create();
    WorkBook.LoadWorkSheetsFromDataSet(new DataSet { Tables = { dt } }, workbook);
    WorkSheet sheet = workbook.WorkSheets[0];

    // Style the header row
    sheet["A1:D1"].Style.Font.Bold = true;
    sheet["A1:D1"].Style.Font.Size = 13;
    sheet["A1:D1"].Style.SetBackgroundColor("#2196F3");
    sheet["A1:D1"].Style.Font.Color = "#FFFFFF";

    // Apply currency format to the Price column (column C, rows 2 onwards)
    sheet["C2:C4"].Style.NumberFormat.Format = "$#,##0.00";

    // Auto-size all columns for readability
    for (int col = 0; col < 4; col++)
    {
        sheet.AutoSizeColumn(col);
    }

    // Freeze the header row so it stays visible when scrolling
    sheet.FreezePanes(0, 0, 1, 0);

    workbook.SaveAs("FormattedExport.xlsx");
}
private void ExportWithFormatting()
{
    DataTable dt = new DataTable("Products");
    dt.Columns.Add("Product", typeof(string));
    dt.Columns.Add("Category", typeof(string));
    dt.Columns.Add("Price", typeof(decimal));
    dt.Columns.Add("InStock", typeof(bool));

    dt.Rows.Add("Widget A", "Hardware", 29.99m, true);
    dt.Rows.Add("Widget B", "Hardware", 49.99m, false);
    dt.Rows.Add("Service Plan", "Support", 199.00m, true);

    WorkBook workbook = WorkBook.Create();
    WorkBook.LoadWorkSheetsFromDataSet(new DataSet { Tables = { dt } }, workbook);
    WorkSheet sheet = workbook.WorkSheets[0];

    // Style the header row
    sheet["A1:D1"].Style.Font.Bold = true;
    sheet["A1:D1"].Style.Font.Size = 13;
    sheet["A1:D1"].Style.SetBackgroundColor("#2196F3");
    sheet["A1:D1"].Style.Font.Color = "#FFFFFF";

    // Apply currency format to the Price column (column C, rows 2 onwards)
    sheet["C2:C4"].Style.NumberFormat.Format = "$#,##0.00";

    // Auto-size all columns for readability
    for (int col = 0; col < 4; col++)
    {
        sheet.AutoSizeColumn(col);
    }

    // Freeze the header row so it stays visible when scrolling
    sheet.FreezePanes(0, 0, 1, 0);

    workbook.SaveAs("FormattedExport.xlsx");
}
$vbLabelText   $csharpLabel

IronXL中提供的格式选项

IronXL通过 IronXl.Styles 命名空间公开了一组丰富的格式化属性:

-字体样式——粗体、斜体、下划线、字体系列和字号 -单元格背景颜色-- 直接接受十六进制颜色字符串 -数字和日期格式——任何 Excel 格式字符串,包括货币、百分比和日期模式 -列宽-- 手动输入像素宽度或使用 AutoSizeColumn 进行自动调整 -冻结窗格——滚动时锁定标题行或列 -单元格边框——所有四个边框均可配置样式和颜色 -合并单元格——将跨行或跨列的单元格合并,用于生成报表标题。

有关完整的 API 参考,请参阅IronXL单元格样式文档IronXL数字格式化文档

在.NET C# 中从 GridView 导出到 Excel:一个简洁的 C# 解决方案:图 3 - 导出的格式化 Excel 文档

如何处理 GridView 导出中的大型数据集?

当 GridView 绑定到数千行数据时,以下几种技巧可以保持导出速度快且内存效率高:

分页和服务器端数据表

不要只导出 GridView 的可见页面。 在调用 WorkBook.LoadWorkSheetsFromDataSet 之前,请从数据源检索完整数据集到 DataTable 中。 IronXL一次性写入多行,无需多次将整个工作簿加载到内存中,因此适用于处理数万行数据。

添加多个工作表

您可以在 DataTable 对象中包含多个 DataSet 对象,以生成具有单独选项卡的工作簿:

DataSet exportSet = new DataSet();
exportSet.Tables.Add(GetEmployeeData());    // Sheet 1
exportSet.Tables.Add(GetDepartmentData());  // Sheet 2
exportSet.Tables.Add(GetSalaryReport());    // Sheet 3

WorkBook workbook = WorkBook.Create();
WorkBook.LoadWorkSheetsFromDataSet(exportSet, workbook);

Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=MultiSheetReport.xlsx");
workbook.SaveAsStream(Response.OutputStream, IronXl.Enum.FileFormat.Xlsx);
Response.Flush();
Response.End();
DataSet exportSet = new DataSet();
exportSet.Tables.Add(GetEmployeeData());    // Sheet 1
exportSet.Tables.Add(GetDepartmentData());  // Sheet 2
exportSet.Tables.Add(GetSalaryReport());    // Sheet 3

WorkBook workbook = WorkBook.Create();
WorkBook.LoadWorkSheetsFromDataSet(exportSet, workbook);

Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=MultiSheetReport.xlsx");
workbook.SaveAsStream(Response.OutputStream, IronXl.Enum.FileFormat.Xlsx);
Response.Flush();
Response.End();
$vbLabelText   $csharpLabel

每个 DataTable.TableName 都会成为 Excel 中的工作表标签名称。 这种模式非常适合将多个视图中的相关数据合并到管理报告中。

相关指南: -如何在 C# 中创建多工作表 Excel 工作簿 -如何在 C# 中读取 Excel 文件 -如何在 C# 中将 DataTable 导出到 Excel -如何在ASP.NET Core中使用IronXL IronXL与 EPPlus 的功能对比

使用IronXL进行 GridView 导出有哪些主要优势?

使用IronXL导出 GridView 数据相比传统的 HTML 封装方法具有明显的优势:

-正版 Excel 文件-- 创建有效的 .xlsx 格式,打开时不会出现浏览器警告或错误消息 无需安装 Office——可在任何没有 Microsoft Excel 或 Office 互操作性的 Web 服务器上运行 -无需 VerifyRenderingInServerForm 覆盖-- 消除了传统代码中繁琐的样板代码变通方案 -完全的格式控制——设置单元格样式、应用数字格式、冻结窗格,并以编程方式创建专业工作表 -支持多工作表——将相关数据集导出为单个工作簿中的不同工作表 -跨平台兼容性——可在 Windows 和 Linux 服务器上正常运行,包括 Docker 容器和 Azure 应用服务。

该库可在NuGet上获取,并支持所有现代.NET目标,包括.NET 10。它还支持读取和写入其他格式,例如 CSV 和 ODS,这使得它成为应用程序中所有电子表格需求的单一依赖项。

要与其他 Excel 库进行并排比较,请参阅IronXL与 ClosedXML 的比较以及IronXL功能概述

下一步计划是什么?

现在您拥有了替换旧版 HtmlTextWriter GridView 导出所需的一切,并可以使用干净、无警告的IronXL实现。 以下是下一步的步骤:

-试用免费版——无需信用卡即可免费试用IronXL 30 天,并在您自己的项目中测试导出代码。 -探索更多IronXL教程——IronXLIronXL涵盖数据导入、单元格公式、图表生成和 Excel 模板工作流程。 -阅读 API 参考文档IronXL API 文档涵盖了 WorkSheet 和样式 API 中的所有方法。 -比较许可选项-- 查看IronXL定价,找到适合您团队规模和部署方案的许可 -有问题尽管提问——如果您遇到任何意外情况, Iron Software支持团队社区论坛随时为您提供帮助。

常见问题解答

为什么要使用IronXL将 GridView 数据导出到 Excel?

IronXL允许您从ASP.NET C# 中的 GridView 创建真正的 XLSX 文件,而不会出现与 HtmlTextWriter 和 StringWriter 相关的常见问题,例如浏览器警告和格式错误。

使用 HtmlTextWriter 导出到 Excel 有哪些局限性?

IronXL经常会生成虚假的 Excel 文件,这可能会导致浏览器警告和格式问题。IronXL 通过生成真正的 Excel 文件来解决这些问题。

IronXL如何改进从 GridView 导出数据的过程?

IronXL简化了从 GridView 导出数据的过程,允许开发人员直接从其ASP.NET应用程序生成格式正确的 Excel 文件,无需使用基于 HTML 的变通方法。

IronXL导出Excel文件时使用什么文件格式?

IronXL将数据导出为真正的 XLSX 文件,确保在 Excel 中打开时具有兼容性和正确的格式。

IronXL能否帮助解决导出到Excel时的格式问题?

是的, IronXL通过创建真正的 Excel 文件来消除格式问题,从而确保数据正确显示,而不会触发浏览器警告。

是否有使用IronXL导出 GridView 数据的代码示例?

是的,该教程包含代码示例,演示如何使用IronXL将 GridView 数据高效地导出到 Excel。

IronXL是否支持从 GridView 导出大型数据集?

IronXL旨在高效处理大型数据集,因此适合将 GridView 中的大量数据导出到 Excel。

与传统的Excel导出方法相比,使用IronXL有哪些优势?

IronXL提供了一种更可靠、更高效的解决方案,消除了浏览器警告,确保了正确的文件格式,并为导出 GridView 数据提供了简单的代码实现。

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