跳至页脚内容
使用 IRONXL

如何在 Blazor 中使用 IronXL 导出到 Excel

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

开始使用 IronXL 导出数据到 Excel

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

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

Install-Package IronXL.Excel

接下来,创建一个用于文件下载的 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)
        {
        // If the program fails to return file
            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)
        {
        // If the program fails to return file
            throw new InvalidOperationException("Failed to generate sales report", ex);
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

This service demonstrates key IronXL features, including creating new workbooks and worksheets, adding formatted headers, populating data rows with imported data from your data source, applying formulas, and handling potential errors. 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 = "";
            // Generate sample data - replace with actual data source
            var salesData = GetSalesData();
            // Generate Excel file
            var fileBytes = ExcelService.GenerateSalesReport(salesData);
            // Trigger download using a memory stream to handle the file
            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.";
            // Log exception details for debugging
        }
        finally
        {
            isExporting = false;
        }
    }
    private List<SalesData> GetSalesData()
    {
        // Return your actual data here
        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 }
        };
    }
}
@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 = "";
            // Generate sample data - replace with actual data source
            var salesData = GetSalesData();
            // Generate Excel file
            var fileBytes = ExcelService.GenerateSalesReport(salesData);
            // Trigger download using a memory stream to handle the file
            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.";
            // Log exception details for debugging
        }
        finally
        {
            isExporting = false;
        }
    }
    private List<SalesData> GetSalesData()
    {
        // Return your actual data here
        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 }
        };
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

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

输出

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

在 Blazor 中使用 IronXL 导出到 Excel:图 1 - Blazor 页面示例

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

在 Blazor 中使用 IronXL 导出到 Excel:图 2 - 数据导出到 Excel 文件

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

IronXL 支持复杂的 Excel 功能,用于专业外观的导出。 For an inventory management scenario, you might add conditional formatting and multiple worksheets:

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");
            // Add headers
            details["A1"].Value = "SKU";
            details["B1"].Value = "Name";
            details["C1"].Value = "Quantity";
            // Apply bold font for headers
            var headerRange = details["A1:C1"];
            headerRange.Style.Font.Bold = true;
            for (int i = 0; i < items.Count; i++)
            {
                var row = i + 2; // start from row 2
                var item = items[i];
                details[$"A{row}"].Value = item.SKU;
                details[$"B{row}"].Value = item.Name;
                details[$"C{row}"].Value = item.Quantity;
                // Highlight low stock items
                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");
            // Add headers
            details["A1"].Value = "SKU";
            details["B1"].Value = "Name";
            details["C1"].Value = "Quantity";
            // Apply bold font for headers
            var headerRange = details["A1:C1"];
            headerRange.Style.Font.Bold = true;
            for (int i = 0; i < items.Count; i++)
            {
                var row = i + 2; // start from row 2
                var item = items[i];
                details[$"A{row}"].Value = item.SKU;
                details[$"B{row}"].Value = item.Name;
                details[$"C{row}"].Value = item.Quantity;
                // Highlight low stock items
                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 中使用 IronXL 导出到 Excel:图 3 - 高级功能示例输出

结论

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

准备好通过专业的 Excel 导出功能来增强你的 Blazor 应用程序了吗? 启动你的免费试用以进行生产部署。

常见问题解答

如何在 Blazor Server 应用中导出 Excel 文件?

您可以使用 IronXL 来导出 Blazor Server 应用中的 Excel 文件。IronXL 允许您直接从服务器创建、格式化和下载 Excel 文件,而无需 Microsoft Office。

在 Blazor 中处理 Excel 文件需要 Microsoft Office 吗?

不需要,IronXL 可以让您在不需要 Microsoft Office 的情况下处理 Excel 文件。它提供了直接在 Blazor 应用程序中创建和操作 Excel 文件的功能。

在 Blazor 中使用 IronXL 导出 Excel 有哪些好处?

IronXL 提供与 Blazor 的无缝集成,让您轻松创建、格式化和导出 Excel 文件。它简化了流程,消除了对 Microsoft Office 的需求,并支持多种 Excel 格式。

IronXL 可以与其他 Blazor 组件集成吗?

是的,IronXL 无缝集成到 Blazor 组件中,使您可以轻松地将 Excel 导出功能添加到您的应用程序中。

可以使用 IronXL 在 Blazor 中格式化 Excel 文件吗?

可以,IronXL 提供全面的功能来格式化 Excel 文件,包括样式化单元格、调整列宽和设置复杂公式,所有这些都可以在您的 Blazor Server 应用程序中实现。

在 Blazor 中导出到 Excel 时如何处理大型数据集?

IronXL 设计为高效处理大型数据集,确保在 Blazor Server 环境中将大量数据导出到 Excel 文件时表现流畅。

IronXL 支持哪些 Excel 文件格式?

IronXL 支持多种 Excel 文件格式,包括 XLS、XLSX 和 CSV,允许您灵活地导出和处理 Blazor 应用中的 Excel 数据。

IronXL 可以用于在 Blazor 中生成报告吗?

绝对可以,IronXL 非常适合在 Blazor 应用程序中生成详细报告。它提供强大的功能来汇编、格式化和导出数据为专业的 Excel 报告。

IronXL 如何在导出 Excel 文件时确保数据完整性?

IronXL 确保数据完整性,准确保留导出过程中数据的结构和格式,是 Blazor 应用程序的可靠解决方案。

有没有方法可以在 Blazor Server 应用中自动生成 Excel 文件?

是的,可以使用 IronXL 来自动生成和导出 Blazor Server 应用中的 Excel 文件,使您可以简化工作流程并提高效率。

Curtis Chau
技术作家

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

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