跳至页脚内容
使用 IRONXL

Blazor 导出到 Excel:在 C# 中使用 IronXL 的完整指南

将数据导出到 Excel 是几乎每个网络应用程序的需求,无论是用于生成报告、库存列表还是客户发票。 在 Blazor 服务器应用程序中,不需要 Microsoft Office 的情况下可靠地完成这一点可能会很有挑战性。 这就是IronXL 的用武之地。 它允许你直接从服务器创建、格式化和下载 Excel 文件,无需安装 Office,并与 Blazor 无缝集成。 在本指南中,你将看到向应用程序添加专业 Excel 导出功能是多么简单。让我们开始吧。

开始使用 IronXL 导出数据到 Excel

在 Blazor 服务器应用程序中设置 IronXL 需要最小的配置。 首先在 Visual Studio 2022 或更高版本中创建一个新的 Blazor 服务器项目,目标为 .NET 6 或更高版本。

通过 NuGet 程序包管理器控制台安装 IronXL(有关其他方法,请参阅我们的完整安装指南):

Install-Package IronXL
Install-Package IronXL
SHELL

接下来,创建一个用于文件下载的 JavaScript 助手函数。 在您的 wwwroot 文件夹中,添加一个名为excelExport.js的新 JavaScript 文件:

window.downloadFileFromStream = async (fileName, contentStreamReference) => {
    const arrayBuffer = await contentStreamReference.arrayBuffer();
    const blob = new Blob([arrayBuffer]);
    const url = URL.createObjectURL(blob);
    const anchorElement = document.createElement('a');
    anchorElement.href = url;
    anchorElement.download = fileName ?? 'export.xlsx';
    anchorElement.click();
    anchorElement.remove();
    URL.revokeObjectURL(url);
}
window.downloadFileFromStream = async (fileName, contentStreamReference) => {
    const arrayBuffer = await contentStreamReference.arrayBuffer();
    const blob = new Blob([arrayBuffer]);
    const url = URL.createObjectURL(blob);
    const anchorElement = document.createElement('a');
    anchorElement.href = url;
    anchorElement.download = fileName ?? 'export.xlsx';
    anchorElement.click();
    anchorElement.remove();
    URL.revokeObjectURL(url);
}
JAVASCRIPT

将此脚本添加到您的_Host.cshtml文件中:

<script src="~/excelExport.js"></script>
<script src="~/excelExport.js"></script>
HTML

这个 JavaScript 函数处理浏览器端下载机制,将来自 Blazor 服务器应用程序的字节流转换成可下载的文件。该函数创建一个临时的 blob URL,触发下载,并清理资源以防止内存泄漏。

如何使用 IronXL 将数据源导出到 Excel 文件?

创建一个 Excel 导出服务来处理你的业务逻辑。 该服务封装了 IronXL 的功能,并为不同的导出场景提供了可重用的方法,在你的 Blazor Excel 导出实现中提供支持:

using IronXL;
using System.IO;
using ExportExcel.Models;
public class ExcelExportService
{
    public byte[] GenerateSalesReport(List<SalesData> salesData)
    {
        try
        {
            var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
            workbook.Metadata.Author = "Sales Department";
            var worksheet = workbook.CreateWorkSheet("Monthly Sales");
            worksheet["A1"].Value = "Date";
            worksheet["B1"].Value = "Product";
            worksheet["C1"].Value = "Quantity";
            worksheet["D1"].Value = "Revenue";
            worksheet["E1"].Value = "Profit Margin";
            var headerRange = worksheet["A1:E1"];
            headerRange.Style.Font.Bold = true;
            headerRange.Style.BackgroundColor = "#4472C4";
            headerRange.Style.Font.Color = "#FFFFFF";
            int row = 2;
            foreach (var sale in salesData)
            {
                worksheet[$"A{row}"].Value = sale.Date.ToString("yyyy-MM-dd");
                worksheet[$"B{row}"].Value = sale.Product ?? "Unknown";
                worksheet[$"C{row}"].Value = sale.Quantity;
                worksheet[$"D{row}"].Value = sale.Revenue;
                worksheet[$"E{row}"].Value = $"=D{row}*0.15";
                row++;
            }
            worksheet.AutoSizeColumn(0, true);
            using var ms = workbook.ToStream();
            return ms.ToArray();
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("Failed to generate sales report", ex);
        }
    }
}
using IronXL;
using System.IO;
using ExportExcel.Models;
public class ExcelExportService
{
    public byte[] GenerateSalesReport(List<SalesData> salesData)
    {
        try
        {
            var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
            workbook.Metadata.Author = "Sales Department";
            var worksheet = workbook.CreateWorkSheet("Monthly Sales");
            worksheet["A1"].Value = "Date";
            worksheet["B1"].Value = "Product";
            worksheet["C1"].Value = "Quantity";
            worksheet["D1"].Value = "Revenue";
            worksheet["E1"].Value = "Profit Margin";
            var headerRange = worksheet["A1:E1"];
            headerRange.Style.Font.Bold = true;
            headerRange.Style.BackgroundColor = "#4472C4";
            headerRange.Style.Font.Color = "#FFFFFF";
            int row = 2;
            foreach (var sale in salesData)
            {
                worksheet[$"A{row}"].Value = sale.Date.ToString("yyyy-MM-dd");
                worksheet[$"B{row}"].Value = sale.Product ?? "Unknown";
                worksheet[$"C{row}"].Value = sale.Quantity;
                worksheet[$"D{row}"].Value = sale.Revenue;
                worksheet[$"E{row}"].Value = $"=D{row}*0.15";
                row++;
            }
            worksheet.AutoSizeColumn(0, true);
            using var ms = workbook.ToStream();
            return ms.ToArray();
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("Failed to generate sales report", ex);
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

该服务演示了 IronXL 的关键功能,包括创建新的工作簿和工作表、添加格式化标题、使用从数据源导入的数据填充数据行、应用公式以及处理潜在错误。 AutoSizeColumn方法确保列能够正确显示,无论内容长度如何。 如需了解更多高级格式设置选项,请参阅我们的单元格样式指南

如何在 Blazor 中实现文件下载?

创建一个使用导出服务并处理用户交互的 Razor 组件:

@page "/excel-export"
@using ExportExcel.Models
@inject ExcelExportService ExcelService
@inject IJSRuntime JS
<h3>Excel Export Dashboard</h3>
<div class="export-section">
    <button class="btn btn-primary" @onclick="ExportSalesReport" disabled="@isExporting">
        @if (isExporting)
        {
            <span>Generating...</span>
        }
        else
        {
            <span>Export Sales Report</span>
        }
    </button>
    @if (!string.IsNullOrEmpty(errorMessage))
    {
        <div class="alert alert-danger mt-2">@errorMessage</div>
    }
</div>
@code {
    private bool isExporting = false;
    private string errorMessage = "";
    private async Task ExportSalesReport()
    {
        try
        {
            isExporting = true;
            errorMessage = "";
            var salesData = GetSalesData();
            var fileBytes = ExcelService.GenerateSalesReport(salesData);
            using var stream = new MemoryStream(fileBytes);
            using var streamRef = new DotNetStreamReference(stream);
            await JS.InvokeVoidAsync("downloadFileFromStream",
                $"SalesReport_{DateTime.Now:yyyyMMdd}.xlsx", streamRef);
        }
        catch (Exception ex)
        {
            errorMessage = "Export failed. Please try again.";
        }
        finally
        {
            isExporting = false;
        }
    }
    private List<SalesData> GetSalesData()
    {
        return new List<SalesData>
        {
            new() { Date = DateTime.Now, Product = "Widget A",
                   Quantity = 100, Revenue = 5000 },
            new() { Date = DateTime.Now.AddDays(-1), Product = "Widget B",
                   Quantity = 75, Revenue = 3750 }
        };
    }
}

这个组件在导出期间提供用户反馈,优雅地处理错误,并生成带时间戳的文件名。 DotNetStreamReference封装器能够高效地将二进制数据流式传输到 JavaScript。

输出

当我们运行代码时,我们会看到页面加载了一个用于处理导出过程的按钮。

Blazor 导出到 Excel:使用 IronXL 在 C# 中实现完整指南:图 1 - Blazor 示例页面

当我们点击按钮时,数据将被保存在新的 Excel 文档中,导出的文件将被下载。

Blazor导出到Excel:使用C#中的IronXL的完整指南:图2 - 数据导出到Excel文件

IronXL 能为你的 Excel 导出添加哪些高级功能?

IronXL 支持复杂的 Excel 功能,用于专业外观的导出。 在库存管理场景中,您可以添加条件格式多个工作表

using IronXL;
using ExportExcel.Models;
using System.IO;
namespace ExportExcel.Services
{
    public class InventoryExportService
    {
        public byte[] GenerateInventoryReport(List<InventoryItem> items)
        {
            var workbook = WorkBook.Create();
            var details = workbook.CreateWorkSheet("Inventory Details");
            details["A1"].Value = "SKU";
            details["B1"].Value = "Name";
            details["C1"].Value = "Quantity";
            var headerRange = details["A1:C1"];
            headerRange.Style.Font.Bold = true;
            for (int i = 0; i < items.Count; i++)
            {
                var row = i + 2;
                var item = items[i];
                details[$"A{row}"].Value = item.SKU;
                details[$"B{row}"].Value = item.Name;
                details[$"C{row}"].Value = item.Quantity;
                if (item.Quantity < item.ReorderLevel)
                {
                    details[$"C{row}"].Style.BackgroundColor = "#FFB6B6";
                }
            }
            using var stream = workbook.ToStream();
            return stream.ToArray();
        }
    }
}
using IronXL;
using ExportExcel.Models;
using System.IO;
namespace ExportExcel.Services
{
    public class InventoryExportService
    {
        public byte[] GenerateInventoryReport(List<InventoryItem> items)
        {
            var workbook = WorkBook.Create();
            var details = workbook.CreateWorkSheet("Inventory Details");
            details["A1"].Value = "SKU";
            details["B1"].Value = "Name";
            details["C1"].Value = "Quantity";
            var headerRange = details["A1:C1"];
            headerRange.Style.Font.Bold = true;
            for (int i = 0; i < items.Count; i++)
            {
                var row = i + 2;
                var item = items[i];
                details[$"A{row}"].Value = item.SKU;
                details[$"B{row}"].Value = item.Name;
                details[$"C{row}"].Value = item.Quantity;
                if (item.Quantity < item.ReorderLevel)
                {
                    details[$"C{row}"].Style.BackgroundColor = "#FFB6B6";
                }
            }
            using var stream = workbook.ToStream();
            return stream.ToArray();
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronXL 轻松处理多个工作表,基于业务规则应用条件格式,并在需要时支持高级 Excel 功能,例如透视表和图表。 如需详细的 API 文档,请访问我们的综合参考指南

Blazor导出到Excel:使用C#中的IronXL的完整指南:图3 - 高级功能示例输出

结论

IronXL 将 Blazor 服务器应用程序中的 Excel 文件生成从复杂的挑战转变为简单的任务。 其直观的 API 消除了对 Microsoft Office 安装的需求,同时提供对高级 Excel 功能的访问。 从简单的数据导出到带有公式和格式化的复杂多表报告,IronXL 以出色的性能和可靠性处理这一切。

准备好通过专业的 Excel 导出功能来增强你的 Blazor 应用程序了吗? 立即开始 IronXL免费试用,或了解我们的生产部署许可选项

Curtis Chau
技术作家

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

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