ASP.NET Excel 导出详细教程

在 Web 应用程序中,将数据导出为 Excel 文件是一项非常常见的需求,ASP.NET 提供了多种方法来实现这一功能,每种方法都有其优缺点和适用场景。

本教程将介绍以下几种主流方法:

  1. 使用 System.IOResponse 流式输出 (最常用,适用于 .NET Framework 和 .NET Core)
  2. 使用 NPOI 库 (推荐,功能强大,兼容性好)
  3. 使用 EPPlus 库 (推荐,仅适用于 .NET Core/.NET 5+)
  4. 使用 ClosedXML 库 (推荐,仅适用于 .NET Core/.NET 5+)

准备工作

在开始之前,请确保你已经:

  1. 创建了一个 ASP.NET Web 应用项目(ASP.NET MVC 或 Razor Pages)。
  2. 准备好要导出的数据源,通常是一个 DataTableList<T> 或数据库查询结果。
  3. 了解基本的 C# 和 HTML 知识。

使用 System.IOResponse 流式输出

这是最传统、最直接的方法,不依赖任何第三方库,它通过生成 HTML 表格并将其流式输出到浏览器,利用 Excel 能够打开 HTML 文件的特性来实现导出。

优点

  • 无需额外库:.NET 框架自带,无需安装 NuGet 包。
  • 实现简单:代码逻辑直接。

缺点

  • 功能有限:无法创建复杂的 Excel 文件,如合并单元格、设置单元格格式、添加图表等。
  • 兼容性问题:导出的文件本质上是 HTML,在旧版 Excel 中可能显示不完美,文件扩展名通常为 .xls.html

实现步骤 (ASP.NET MVC 示例)

创建 Action 方法

在 Controller 中创建一个 Action,用于处理导出请求。

using System.Collections.Generic;
using System.IO;
using System.Web.Mvc;
public class ExportController : Controller
{
    public ActionResult ExportToHtmlExcel()
    {
        // 1. 准备数据源 (这里用硬编码的 List<T> 作为示例)
        var products = new List<Product>
        {
            new Product { Id = 1, Name = "笔记本电脑", Price = 5999, Stock = 100 },
            new Product { Id = 2, Name = "无线鼠标", Price = 99, Stock = 500 },
            new Product { Id = 3, Name = "机械键盘", Price = 399, Stock = 200 }
        };
        // 2. 构建一个 HTML 表格字符串
        var html = "<table border='1'>";
        html += "<thead><tr><th>ID</th><th>产品名称</th><th>价格</th><th>库存</th></tr></thead>";
        html += "<tbody>";
        foreach (var item in products)
        {
            html += "<tr>";
            html += $"<td>{item.Id}</td>";
            html += $"<td>{item.Name}</td>";
            html += $"<td>{item.Price}</td>";
            html += $"<td>{item.Stock}</td>";
            html += "</tr>";
        }
        html += "</tbody>";
        html += "</table>";
        // 3. 设置响应头,告诉浏览器这是一个要下载的文件
        Response.Clear();
        Response.Buffer = true;
        Response.AddHeader("content-disposition", "attachment;filename=Products_" + DateTime.Now.ToString("yyyyMMdd") + ".xls");
        Response.Charset = "UTF-8";
        Response.ContentType = "application/vnd.ms-excel"; // 指定内容类型为 Excel
        Response.Output.Write(html);
        Response.Flush();
        Response.End();
        // 因为已经手动输出了响应,所以这里返回 null
        return null;
    }
}

创建 Model (Product.cs)

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Stock { get; set; }
}

创建 View (用于测试)

Views/Export 文件夹下创建一个 Index.cshtml 文件。

@{
    ViewBag.Title = "Excel Export Demo";
}
<h2>Excel Export Demo</h2>
<p>点击下方按钮导出产品列表为 Excel 文件。</p>
@Html.ActionLink("导出为 Excel (HTML 方式)", "ExportToHtmlExcel", "Export", null, new { @class = "btn btn-primary" })

运行并测试

运行项目,访问首页,点击链接,浏览器会提示你下载一个名为 Products_20251027.xls 的文件,用 Excel 打开即可看到数据。


使用 NPOI 库 (强烈推荐)

NPOI 是一个开源的 .NET 库,可以操作 Office 2003/2007+ 的所有格式(.xls.xlsx),无需安装 Office,它功能非常强大,是处理 Excel 导出/导入的首选之一。

优点

  • 功能强大:支持几乎所有 Excel 操作,包括样式、合并单元格、图片、公式等。
  • 兼容性好:同时支持 .xls (HSSFWorkbook) 和 .xlsx (XSSFWorkbook) 格式。
  • 无需 Office:服务器端无需安装 Office 软件。

缺点

  • 需要安装 NuGet 包。

实现步骤

安装 NPOI

在 NuGet 包管理器控制台中运行:

Install-Package NPOI

创建 Action 方法

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
using System.Web.Mvc;
public class ExportController : Controller
{
    public ActionResult ExportWithNpoi()
    {
        // 1. 准备数据源
        var products = new List<Product>
        {
            new Product { Id = 1, Name = "笔记本电脑", Price = 5999, Stock = 100 },
            new Product { Id = 2, Name = "无线鼠标", Price = 99, Stock = 500 },
            new Product { Id = 3, Name = "机械键盘", Price = 399, Stock = 200 }
        };
        // 2. 创建一个工作簿 (这里使用 .xlsx 格式)
        IWorkbook workbook = new XSSFWorkbook();
        ISheet sheet = workbook.CreateSheet("产品列表");
        // 3. 创建表头样式
        ICellStyle headerStyle = workbook.CreateCellStyle();
        headerStyle.FillForegroundColor = IndexedColors.Grey25.Index;
        headerStyle.FillPattern = FillPattern.SolidForeground;
        IFont headerFont = workbook.CreateFont();
        headerFont.FontHeightInPoints = 10;
        headerFont.Color = IndexedColors.White.Index;
        headerFont.Boldweight = (short)FontBoldWeight.Bold;
        headerStyle.SetFont(headerFont);
        // 4. 创建行和单元格 (表头)
        IRow headerRow = sheet.CreateRow(0);
        headerRow.CreateCell(0).SetCellValue("ID");
        headerRow.CreateCell(1).SetCellValue("产品名称");
        headerRow.CreateCell(2).SetCellValue("价格");
        headerRow.CreateCell(3).SetCellValue("库存");
        // 应用表头样式
        for (int i = 0; i < 4; i++)
        {
            headerRow.GetCell(i).CellStyle = headerStyle;
        }
        // 5. 填充数据
        int rowIndex = 1;
        foreach (var item in products)
        {
            IRow dataRow = sheet.CreateRow(rowIndex);
            dataRow.CreateCell(0).SetCellValue(item.Id);
            dataRow.CreateCell(1).SetCellValue(item.Name);
            dataRow.CreateCell(2).SetCellValue(item.Price);
            dataRow.CreateCell(3).SetCellValue(item.Stock);
            rowIndex++;
        }
        // 6. 自动调整列宽
        for (int i = 0; i < 4; i++)
        {
            sheet.AutoSizeColumn(i);
        }
        // 7. 将工作簿写入流
        using (var stream = new MemoryStream())
        {
            workbook.Write(stream);
            stream.Flush();
            // 8. 设置响应头并返回文件
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader("content-disposition", "attachment;filename=Products_NPOI_" + DateTime.Now.ToString("yyyyMMdd") + ".xlsx");
            Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            Response.BinaryWrite(stream.ToArray());
            Response.Flush();
            Response.End();
        }
        return null;
    }
}

更新 View

Index.cshtml 中添加新的