Przejdź do treści stopki
KORZYSTANIE Z IRONXL

Jak eksportować pliki Excel w Blazor przy użyciu IronXL

Eksportowanie danych do Excela jest czymś, czego potrzebuje niemal każda aplikacja internetowa Blazor — niezależnie od tego, czy generujesz raporty sprzedaży, listy zapasów czy faktury dla klientów. W aplikacji Blazor Server niezawodne wykonanie tego zadania bez konieczności korzystania z pakietu Microsoft Office może wydawać się trudne. IronXL sprawia, że jest to proste: możesz tworzyć, formatować i pobierać pliki Excel bezpośrednio z serwera, bez konieczności instalowania pakietu Office. Ten przewodnik przeprowadzi Cię przez proces tworzenia gotowej do użycia funkcji eksportu do Excela w Blazorze przy użyciu IronXL — od konfiguracji projektu i projektowania usług po zaawansowane formatowanie i raporty wielarkuszowe.

Jak skonfigurować IronXL w projekcie Blazor Server?

Przed napisaniem jakiejkolwiek logiki eksportu należy dodać IronXL do projektu Blazor Server i skonfigurować pomocnik pobierania po stronie przeglądarki.

Tworzenie projektu Blazor Server

Zacznij od utworzenia nowego projektu Blazor Server w Visual Studio 2022 lub nowszym, przeznaczonego dla .NET 10. Gdy projekt będzie gotowy, zainstaluj IronXL za pomocą konsoli NuGet Package Manager:

Install-Package IronXL.Excel

IronXL współpracuje z platformą .NET 6 i nowszymi wersjami, więc istniejące projekty Blazor mogą z niego korzystać bez konieczności aktualizacji frameworka. Aby zapoznać się z alternatywnymi metodami instalacji — takimi jak interfejs użytkownika NuGet lub CLI — zapoznaj się z instrukcją instalacji IronXL.

Dodawanie narzędzia JavaScript Download Helper

Blazor Server działa po stronie serwera, więc uruchomienie pobierania pliku wymaga niewielkiego mostka JavaScript. W swoim folderze wwwroot dodaj plik o nazwie excelExport.js:

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

Zawierz ten skrypt w pliku _Host.cshtml (lub App.razor w .NET 8+):

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

Ta funkcja konwertuje strumień bajtów z Blazora na tymczasowy adres URL obiektu blob, uruchamia pobieranie w przeglądarce, a następnie czyści obiekt URL, aby zapobiec wyciekom pamięci. Jest on celowo minimalistyczny — ciężka praca odbywa się w języku C# na serwerze.

Zacznij z IronXL teraz.
green arrow pointer

Jak Stworzyć Usługę Eksportu Excel w C#?

Oddzielenie generowania arkuszy Excel od komponentów Razor pozwala zachować możliwość testowania kodu i ponownego wykorzystania go na wielu stronach. Poniższy wzorzec umieszcza IronXL w dedykowanej klasie usługowej.

Tworzenie usługi ExcelExportService

Utwórz nowy plik Services/ExcelExportService.cs:

using IronXL;
using System.IO;
using ExportExcel.Models;

public class ExcelExportService
{
    public byte[] GenerateSalesReport(List<SalesData> salesData)
    {
        var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
        workbook.Metadata.Author = "Sales Department";

        var worksheet = workbook.CreateWorkSheet("Monthly Sales");

        // Add column headers
        worksheet["A1"].Value = "Date";
        worksheet["B1"].Value = "Product";
        worksheet["C1"].Value = "Quantity";
        worksheet["D1"].Value = "Revenue";
        worksheet["E1"].Value = "Profit Margin";

        // Style the header row
        var headerRange = worksheet["A1:E1"];
        headerRange.Style.Font.Bold = true;
        headerRange.Style.BackgroundColor = "#4472C4";
        headerRange.Style.Font.Color = "#FFFFFF";

        // Populate data rows
        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();
    }
}
using IronXL;
using System.IO;
using ExportExcel.Models;

public class ExcelExportService
{
    public byte[] GenerateSalesReport(List<SalesData> salesData)
    {
        var workbook = WorkBook.Create(ExcelFileFormat.XLSX);
        workbook.Metadata.Author = "Sales Department";

        var worksheet = workbook.CreateWorkSheet("Monthly Sales");

        // Add column headers
        worksheet["A1"].Value = "Date";
        worksheet["B1"].Value = "Product";
        worksheet["C1"].Value = "Quantity";
        worksheet["D1"].Value = "Revenue";
        worksheet["E1"].Value = "Profit Margin";

        // Style the header row
        var headerRange = worksheet["A1:E1"];
        headerRange.Style.Font.Bold = true;
        headerRange.Style.BackgroundColor = "#4472C4";
        headerRange.Style.Font.Color = "#FFFFFF";

        // Populate data rows
        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();
    }
}
Imports IronXL
Imports System.IO
Imports ExportExcel.Models

Public Class ExcelExportService
    Public Function GenerateSalesReport(salesData As List(Of SalesData)) As Byte()
        Dim workbook = WorkBook.Create(ExcelFileFormat.XLSX)
        workbook.Metadata.Author = "Sales Department"

        Dim worksheet = workbook.CreateWorkSheet("Monthly Sales")

        ' Add column headers
        worksheet("A1").Value = "Date"
        worksheet("B1").Value = "Product"
        worksheet("C1").Value = "Quantity"
        worksheet("D1").Value = "Revenue"
        worksheet("E1").Value = "Profit Margin"

        ' Style the header row
        Dim headerRange = worksheet("A1:E1")
        headerRange.Style.Font.Bold = True
        headerRange.Style.BackgroundColor = "#4472C4"
        headerRange.Style.Font.Color = "#FFFFFF"

        ' Populate data rows
        Dim row As Integer = 2
        For Each sale In salesData
            worksheet($"A{row}").Value = sale.Date.ToString("yyyy-MM-dd")
            worksheet($"B{row}").Value = If(sale.Product, "Unknown")
            worksheet($"C{row}").Value = sale.Quantity
            worksheet($"D{row}").Value = sale.Revenue
            worksheet($"E{row}").Value = $"=D{row}*0.15"
            row += 1
        Next

        worksheet.AutoSizeColumn(0, True)

        Using ms = workbook.ToStream()
            Return ms.ToArray()
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Rejestracja usługi

Dodaj usługę do kontenera DI w Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<ExcelExportService>();

var app = builder.Build();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<ExcelExportService>();

var app = builder.Build();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
Imports Microsoft.AspNetCore.Builder
Imports Microsoft.Extensions.DependencyInjection

Dim builder = WebApplication.CreateBuilder(args)

builder.Services.AddRazorPages()
builder.Services.AddServerSideBlazor()
builder.Services.AddScoped(Of ExcelExportService)()

Dim app = builder.Build()
app.MapBlazorHub()
app.MapFallbackToPage("/_Host")
app.Run()
$vbLabelText   $csharpLabel

Usługa ta prezentuje kilka kluczowych możliwości IronXL. Możesz tworzyć nowe skoroszyty i arkusze za pomocą jednego wywołania metody, stosować stylizowane nagłówki, wypełniać wiersze z dowolnego źródła danych i osadzać formuły Excela takie jak =D2*0.15. Wywołanie AutoSizeColumn zapewnia, że kolumny są wystarczająco szerokie, aby poprawnie wyświetlać swoją zawartość, niezależnie od długości danych. Więcej opcji formatowania znajdziesz w przewodniku po stylach komórek.

Jak uruchomić pobieranie pliku Excel z komponentu Blazor?

Po uruchomieniu usługi potrzebny jest komponent Razor, który ją wywołuje i przekazuje wynikowe bajty do przeglądarki.

Pisanie komponentu Razor

Utwórz stronę w Pages/ExcelExportDashboard.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)
        {
            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 }
        };
    }
}
@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)
        {
            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 }
        };
    }
}
Imports ExportExcel.Models
Imports Microsoft.JSInterop

@page "/excel-export"

@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 Then
            <span>Generating...</span>
        Else
            <span>Export Sales Report</span>
        End If
    </button>

    @If Not String.IsNullOrEmpty(errorMessage) Then
        <div class="alert alert-danger mt-2">@errorMessage</div>
    End If
</div>

@code {
    Private isExporting As Boolean = False
    Private errorMessage As String = ""

    Private Async Function ExportSalesReport() As Task
        Try
            isExporting = True
            errorMessage = ""

            Dim salesData = GetSalesData()
            Dim fileBytes = ExcelService.GenerateSalesReport(salesData)

            Using stream As New MemoryStream(fileBytes)
                Using streamRef As New DotNetStreamReference(stream)
                    Await JS.InvokeVoidAsync(
                        "downloadFileFromStream",
                        $"SalesReport_{DateTime.Now:yyyyMMdd}.xlsx",
                        streamRef
                    )
                End Using
            End Using
        Catch ex As Exception
            errorMessage = "Export failed. Please try again."
        Finally
            isExporting = False
        End Try
    End Function

    Private Function GetSalesData() As List(Of SalesData)
        Return New List(Of SalesData) From {
            New SalesData() With {.Date = DateTime.Now, .Product = "Widget A", .Quantity = 100, .Revenue = 5000},
            New SalesData() With {.Date = DateTime.Now.AddDays(-1), .Product = "Widget B", .Quantity = 75, .Revenue = 3750}
        }
    End Function
}
$vbLabelText   $csharpLabel

Funkcje komponentu

Flaga isExporting dezaktywuje przycisk podczas generowania, zapobiegając podwójnym żądaniom. Osłona DotNetStreamReference obsługuje wydajne strumieniowanie binarne z pamięci .NET do funkcji JavaScript — unikając dużych ciągów base64, które mogłyby powiększać rozmiar ładunku. Pliki z nazwami opatrzonymi znacznikami czasowymi, takie jak SalesReport_20260228.xlsx, utrzymują pobierania w porządku bez dodatkowej konfiguracji.

Gdy nawigujesz do /excel-export w przeglądarce, strona kokpitu wczytuje się z przyciskiem eksportu:

Blazor Eksport do Excel: Kompletny przewodnik używania IronXL w C#: Obraz 1 - Przykładowa strona Blazor

Kliknięcie przycisku powoduje wygenerowanie arkusza kalkulacyjnego, a przeglądarka automatycznie pobiera plik:

Blazor Eksport do Excel: Kompletny przewodnik używania IronXL w C#: Obraz 2 - Dane wyeksportowane do pliku Excel

Jakie zaawansowane formatowanie można zastosować w eksportach do programu Excel?

Eksport podstawowych danych zaspokaja wiele potrzeb, ale aplikacje produkcyjne często wymagają formatowania warunkowego, wielu arkuszy lub walidacji danych. IronXL obsługuje wszystkie te technologie natywnie.

Formatowanie warunkowe dla raportów magazynowych

Następująca usługa zaznacza na czerwono pozycje o niskim stanie magazynowym — jest to powszechny wymóg w aplikacjach do zarządzania magazynem lub zapasami:

using IronXL;
using ExportExcel.Models;
using System.IO;

public class InventoryExportService
{
    public byte[] GenerateInventoryReport(List<InventoryItem> items)
    {
        var workbook = WorkBook.Create();
        var details = workbook.CreateWorkSheet("Inventory Details");

        // Column headers
        details["A1"].Value = "SKU";
        details["B1"].Value = "Name";
        details["C1"].Value = "Quantity";
        details["D1"].Value = "Reorder Level";
        details["E1"].Value = "Status";

        var headerRange = details["A1:E1"];
        headerRange.Style.Font.Bold = true;
        headerRange.Style.BackgroundColor = "#2E75B6";
        headerRange.Style.Font.Color = "#FFFFFF";

        for (int i = 0; i < items.Count; i++)
        {
            int 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;
            details[$"D{row}"].Value = item.ReorderLevel;
            details[$"E{row}"].Value = item.Quantity < item.ReorderLevel
                ? "Reorder Required"
                : "OK";

            if (item.Quantity < item.ReorderLevel)
            {
                // Highlight the entire row for low-stock items
                details[$"A{row}:E{row}"].Style.BackgroundColor = "#FFB6B6";
                details[$"C{row}"].Style.Font.Bold = true;
            }
        }

        details.AutoSizeColumn(0, true);
        details.AutoSizeColumn(1, true);

        using var stream = workbook.ToStream();
        return stream.ToArray();
    }
}
using IronXL;
using ExportExcel.Models;
using System.IO;

public class InventoryExportService
{
    public byte[] GenerateInventoryReport(List<InventoryItem> items)
    {
        var workbook = WorkBook.Create();
        var details = workbook.CreateWorkSheet("Inventory Details");

        // Column headers
        details["A1"].Value = "SKU";
        details["B1"].Value = "Name";
        details["C1"].Value = "Quantity";
        details["D1"].Value = "Reorder Level";
        details["E1"].Value = "Status";

        var headerRange = details["A1:E1"];
        headerRange.Style.Font.Bold = true;
        headerRange.Style.BackgroundColor = "#2E75B6";
        headerRange.Style.Font.Color = "#FFFFFF";

        for (int i = 0; i < items.Count; i++)
        {
            int 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;
            details[$"D{row}"].Value = item.ReorderLevel;
            details[$"E{row}"].Value = item.Quantity < item.ReorderLevel
                ? "Reorder Required"
                : "OK";

            if (item.Quantity < item.ReorderLevel)
            {
                // Highlight the entire row for low-stock items
                details[$"A{row}:E{row}"].Style.BackgroundColor = "#FFB6B6";
                details[$"C{row}"].Style.Font.Bold = true;
            }
        }

        details.AutoSizeColumn(0, true);
        details.AutoSizeColumn(1, true);

        using var stream = workbook.ToStream();
        return stream.ToArray();
    }
}
Imports IronXL
Imports ExportExcel.Models
Imports System.IO

Public Class InventoryExportService
    Public Function GenerateInventoryReport(items As List(Of InventoryItem)) As Byte()
        Dim workbook = WorkBook.Create()
        Dim details = workbook.CreateWorkSheet("Inventory Details")

        ' Column headers
        details("A1").Value = "SKU"
        details("B1").Value = "Name"
        details("C1").Value = "Quantity"
        details("D1").Value = "Reorder Level"
        details("E1").Value = "Status"

        Dim headerRange = details("A1:E1")
        headerRange.Style.Font.Bold = True
        headerRange.Style.BackgroundColor = "#2E75B6"
        headerRange.Style.Font.Color = "#FFFFFF"

        For i As Integer = 0 To items.Count - 1
            Dim row As Integer = i + 2
            Dim item = items(i)

            details($"A{row}").Value = item.SKU
            details($"B{row}").Value = item.Name
            details($"C{row}").Value = item.Quantity
            details($"D{row}").Value = item.ReorderLevel
            details($"E{row}").Value = If(item.Quantity < item.ReorderLevel, "Reorder Required", "OK")

            If item.Quantity < item.ReorderLevel Then
                ' Highlight the entire row for low-stock items
                details($"A{row}:E{row}").Style.BackgroundColor = "#FFB6B6"
                details($"C{row}").Style.Font.Bold = True
            End If
        Next

        details.AutoSizeColumn(0, True)
        details.AutoSizeColumn(1, True)

        Using stream = workbook.ToStream()
            Return stream.ToArray()
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronXL stosuje formatowanie na poziomie komórek w oparciu o wartości danych w momencie generowania. Można również stosować reguły formatowania warunkowego w sposób deklaratywny lub zarządzać wieloma arkuszami w ramach tego samego skoroszytu — na przykład jednym arkuszem dla aktualnych stanów magazynowych, a innym dla historycznych zamówień.

Dodawanie wielu arkuszy do jednego eksportu

Podział danych na logiczne arkusze poprawia czytelność bez konieczności pobierania osobnych plików:

public byte[] GenerateMultiSheetReport(
    List<SalesData> sales,
    List<InventoryItem> inventory)
{
    var workbook = WorkBook.Create(ExcelFileFormat.XLSX);

    // Sheet 1 -- Sales summary
    var salesSheet = workbook.CreateWorkSheet("Sales");
    salesSheet["A1"].Value = "Date";
    salesSheet["B1"].Value = "Revenue";
    salesSheet["A1:B1"].Style.Font.Bold = true;

    for (int i = 0; i < sales.Count; i++)
    {
        salesSheet[$"A{i + 2}"].Value = sales[i].Date.ToString("yyyy-MM-dd");
        salesSheet[$"B{i + 2}"].Value = sales[i].Revenue;
    }

    // Sheet 2 -- Inventory snapshot
    var invSheet = workbook.CreateWorkSheet("Inventory");
    invSheet["A1"].Value = "SKU";
    invSheet["B1"].Value = "Name";
    invSheet["C1"].Value = "Quantity";
    invSheet["A1:C1"].Style.Font.Bold = true;

    for (int i = 0; i < inventory.Count; i++)
    {
        invSheet[$"A{i + 2}"].Value = inventory[i].SKU;
        invSheet[$"B{i + 2}"].Value = inventory[i].Name;
        invSheet[$"C{i + 2}"].Value = inventory[i].Quantity;
    }

    using var stream = workbook.ToStream();
    return stream.ToArray();
}
public byte[] GenerateMultiSheetReport(
    List<SalesData> sales,
    List<InventoryItem> inventory)
{
    var workbook = WorkBook.Create(ExcelFileFormat.XLSX);

    // Sheet 1 -- Sales summary
    var salesSheet = workbook.CreateWorkSheet("Sales");
    salesSheet["A1"].Value = "Date";
    salesSheet["B1"].Value = "Revenue";
    salesSheet["A1:B1"].Style.Font.Bold = true;

    for (int i = 0; i < sales.Count; i++)
    {
        salesSheet[$"A{i + 2}"].Value = sales[i].Date.ToString("yyyy-MM-dd");
        salesSheet[$"B{i + 2}"].Value = sales[i].Revenue;
    }

    // Sheet 2 -- Inventory snapshot
    var invSheet = workbook.CreateWorkSheet("Inventory");
    invSheet["A1"].Value = "SKU";
    invSheet["B1"].Value = "Name";
    invSheet["C1"].Value = "Quantity";
    invSheet["A1:C1"].Style.Font.Bold = true;

    for (int i = 0; i < inventory.Count; i++)
    {
        invSheet[$"A{i + 2}"].Value = inventory[i].SKU;
        invSheet[$"B{i + 2}"].Value = inventory[i].Name;
        invSheet[$"C{i + 2}"].Value = inventory[i].Quantity;
    }

    using var stream = workbook.ToStream();
    return stream.ToArray();
}
Public Function GenerateMultiSheetReport( _
    sales As List(Of SalesData), _
    inventory As List(Of InventoryItem)) As Byte()

    Dim workbook = WorkBook.Create(ExcelFileFormat.XLSX)

    ' Sheet 1 -- Sales summary
    Dim salesSheet = workbook.CreateWorkSheet("Sales")
    salesSheet("A1").Value = "Date"
    salesSheet("B1").Value = "Revenue"
    salesSheet("A1:B1").Style.Font.Bold = True

    For i As Integer = 0 To sales.Count - 1
        salesSheet($"A{i + 2}").Value = sales(i).Date.ToString("yyyy-MM-dd")
        salesSheet($"B{i + 2}").Value = sales(i).Revenue
    Next

    ' Sheet 2 -- Inventory snapshot
    Dim invSheet = workbook.CreateWorkSheet("Inventory")
    invSheet("A1").Value = "SKU"
    invSheet("B1").Value = "Name"
    invSheet("C1").Value = "Quantity"
    invSheet("A1:C1").Style.Font.Bold = True

    For i As Integer = 0 To inventory.Count - 1
        invSheet($"A{i + 2}").Value = inventory(i).SKU
        invSheet($"B{i + 2}").Value = inventory(i).Name
        invSheet($"C{i + 2}").Value = inventory(i).Quantity
    Next

    Using stream = workbook.ToStream()
        Return stream.ToArray()
    End Using
End Function
$vbLabelText   $csharpLabel

Pełny opis dokumentacji API obejmujący właściwości skoroszytów, operacje na zakresach i obsługę wykresów można znaleźć w dokumentacji API IronXL.

Blazor Eksport do Excel: Kompletny przewodnik używania IronXL w C#: Obraz 3 - Przykład zaawansowanych funkcji

Jak skutecznie radzisz sobie z błędami i dużymi zbiorami danych?

Operacje eksportu do programu Excel mogą zakończyć się niepowodzeniem bez wyświetlania komunikatu lub spowodować spadek wydajności w przypadku dużych zbiorów danych. Poniższe wzorce uwzględniają obie te kwestie.

Obsługa błędów w warstwie usług

Umieszczenie logiki generowania w usłudze (a nie w komponencie) zapewnia spójność obsługi błędów we wszystkich wywołujących. Zalecanym wzorcem jest pozwolenie na propagację wyjątków IronXL, a następnie opakowanie ich w wyjątek specyficzny dla danej dziedziny wraz z kontekstem informującym, który raport zakończył się niepowodzeniem:

Umieść blok try/catch wokół generowania skoroszytu w GenerateSalesReport, łapiąc Exception i ponownie rzucając jako InvalidOperationException("Failed to generate sales report", ex). W komponencie Blazor, przechwyć InvalidOperationException i wyświetl użytkownikowi przyjazny komunikat bez ujawniania wewnętrznych szczegółów. Zaloguj wewnętrzny wyjątek przy użyciu ILogger<t> wstrzykniętego do konstruktora usługi, aby zespół deweloperski mógł śledzić awarie do konkretnej operacji na skoroszycie. Nigdy nie ujawniaj użytkownikom końcowym surowych komunikatów o wyjątkach — ścieżki plików, adresy pamięci lub ślady stosu mogą ujawnić wewnętrzne dane serwera.

Zobacz najlepsze praktyki dotyczące obsługi błędów w oficjalnej dokumentacji Microsoft, aby uzyskać wskazówki dotyczące strukturalnego rejestrowania błędów w Blazor. Więcej wskazówek na temat budowania testowalnych usług w .NET znajdziesz w dokumentacji wtryskiwania zależności firmy Microsoft, która wyjaśnia, jak rejestrować i rozwiązywać usługi o zasięgu lokalnym, co jest dokładnie wzorcem używanym tutaj z ExcelExportService.

Kwestie związane z wydajnością w przypadku dużych zbiorów danych

W przypadku zbiorów danych przekraczających kilka tysięcy wierszy warto rozważyć następujące podejścia:

Strategie wydajności eksportu do Excela
Strategia Kiedy stosować Wsparcie techniczne IronXL
Przejdź bezpośrednio do odpowiedzi Files >10 MB workbook.ToStream()
Paginuj dane przed eksportem Eksporty sterowane interfejsem użytkownika z filtrami Zastosuj w usłudze przed utworzeniem skoroszytu
Zadanie w tle + link do pobrania Reports taking >5 seconds Połącz z SignalR lub pollingiem
Wyłącz opcję AutoSizeColumn w dużych arkuszach Sheets with >500 rows Zamiast tego ustaw stałą szerokość kolumn

Metoda ToStream() IronXL zapisuje bezpośrednio do strumienia wyjściowego bez wcześniej ładowania całego pliku do tablicy bajtów, co utrzymuje zużycie pamięci na niższym poziomie dla dużych skoroszytów. Dla dodatkowych wskazówek dotyczących wydajności, zobacz odczyt i zapis dużych plików Excel z IronXL.

Jakie inne funkcje programu Excel obsługuje IronXL?

Oprócz podstawowego eksportu, IronXL oferuje szeroki zakres funkcji programu Excel, które zaspokajają rzeczywiste wymagania dotyczące raportowania.

Formuły, nazwane zakresy i formatowanie liczb

Możesz osadzić dowolną formułę Excel, używając tej samej składni, którą wpisałbyś bezpośrednio w komórce. IronXL oblicza formuły w momencie odczytu, dzięki czemu użytkownicy wygenerowanego pliku widzą wyniki obliczeń zaraz po otwarciu arkusza kalkulacyjnego. Nazwane zakresy sprawiają, że formuły są bardziej czytelne i łatwiejsze w utrzymaniu w dłuższej perspektywie:

// Aggregate formulas on a summary row
worksheet["E2"].Value = "=SUM(D2:D100)";
worksheet["F2"].Value = "=AVERAGE(C2:C100)";
worksheet["G2"].Value = "=COUNTIF(B2:B100,\"Widget A\")";

// Named ranges improve formula readability
worksheet["D2:D100"].Name = "RevenueColumn";
worksheet["E2"].Value = "=SUM(RevenueColumn)";

// Number and date formatting prevents type misinterpretation
worksheet["D2"].Value = 12345.67m;
worksheet["D2"].FormatString = "#,##0.00";
worksheet["A2"].Value = DateTime.Now;
worksheet["A2"].FormatString = "dd/MM/yyyy";
// Aggregate formulas on a summary row
worksheet["E2"].Value = "=SUM(D2:D100)";
worksheet["F2"].Value = "=AVERAGE(C2:C100)";
worksheet["G2"].Value = "=COUNTIF(B2:B100,\"Widget A\")";

// Named ranges improve formula readability
worksheet["D2:D100"].Name = "RevenueColumn";
worksheet["E2"].Value = "=SUM(RevenueColumn)";

// Number and date formatting prevents type misinterpretation
worksheet["D2"].Value = 12345.67m;
worksheet["D2"].FormatString = "#,##0.00";
worksheet["A2"].Value = DateTime.Now;
worksheet["A2"].FormatString = "dd/MM/yyyy";
' Aggregate formulas on a summary row
worksheet("E2").Value = "=SUM(D2:D100)"
worksheet("F2").Value = "=AVERAGE(C2:C100)"
worksheet("G2").Value = "=COUNTIF(B2:B100,""Widget A"")"

' Named ranges improve formula readability
worksheet("D2:D100").Name = "RevenueColumn"
worksheet("E2").Value = "=SUM(RevenueColumn)"

' Number and date formatting prevents type misinterpretation
worksheet("D2").Value = 12345.67D
worksheet("D2").FormatString = "#,##0.00"
worksheet("A2").Value = DateTime.Now
worksheet("A2").FormatString = "dd/MM/yyyy"
$vbLabelText   $csharpLabel

Aby zdefiniować nazwane zakresy i ustawić format liczb wyraźnie, IronXL wystawia oba jako właściwości na obiekcie zakresu. Zapobiega to traktowaniu przez program Excel wartości walutowych jako zwykłego tekstu — jest to częsty problem podczas eksportowania danych finansowych z baz danych, które przechowują wartości jako ciągi znaków.

Obsługiwane formaty plików Excel

IronXL może czytać i zapisywać różne formaty Excel, w tym .xlsx, .xls, .csv i .tsv. Format jest określany w momencie zapisywania, więc ta sama klasa usługi może obsługiwać zarówno eksport do Excel, jak i CSV przy niewielkiej zmianie parametrów:

// Export as CSV for systems that consume flat files
workbook.SaveAs("report.csv");

// Or stream as CSV for download
using var ms = workbook.ToStream(ExcelFileFormat.CSV);
// Export as CSV for systems that consume flat files
workbook.SaveAs("report.csv");

// Or stream as CSV for download
using var ms = workbook.ToStream(ExcelFileFormat.CSV);
' Export as CSV for systems that consume flat files
workbook.SaveAs("report.csv")

' Or stream as CSV for download
Using ms As Stream = workbook.ToStream(ExcelFileFormat.CSV)
End Using
$vbLabelText   $csharpLabel

Ta elastyczność ma znaczenie w integracjach, w których systemy niższego szczebla — takie jak platformy ERP lub hurtownie danych — oczekują określonego formatu plików. Aby zapoznać się z pełnym porównaniem funkcji IronXL i innych bibliotek Excel, odwiedź stronę funkcji IronXL.

Microsoft zapewnia dobrą referencję do rozumienia formatów plików OOXML, jeśli potrzebujesz zrozumieć wewnętrzną strukturę plików .xlsx podczas debugowania niespodziewanego wyniku. Pakiet NuGet dla IronXL jest również wymieniony na stronie NuGet.org wraz z pełną historią wersji i informacjami o kompatybilności.

Jak rozpocząć pracę z IronXL w projektach Blazor?

IronXL jest dostępny na bezpłatnej licencji deweloperskiej, która pozwala na tworzenie i testowanie bez ograniczeń czasowych. W przypadku aplikacji produkcyjnych wymagana jest licencja wdrożeniowa.

Bezpłatną wersję próbną można pobrać bezpośrednio z NuGet — do rozpoczęcia nie jest wymagana rejestracja. Kiedy będziesz gotowy do wdrożenia, zapoznaj się z opcjami licencyjnymi IronXL, aby znaleźć plan dostosowany do skali aplikacji.

IronXL działa we wszystkich głównych typach aplikacji .NET — Blazor Server, Blazor WebAssembly (renderowane po stronie serwera), ASP.NET Core MVC, aplikacjach konsolowych i aplikacjach desktopowych dla systemu Windows. Biblioteka jest przeznaczona dla .NET Standard 2.0, więc jest kompatybilna z każdą obsługiwaną wersją .NET od .NET Framework 4.6.2 do .NET 10. Jeśli projekt wymaga również generowania plików PDF, IronPDF integruje się z IronXL bez żadnych konfliktów, umożliwiając eksport danych jako Excel lub PDF z tej samej warstwy usługowej.

Aby zapoznać się z innymi przykładami dotyczącymi Blazora, zobacz samouczek dotyczący eksportu do programu Excel w Blazorze oraz przewodnik po eksporcie w ASP.NET Core. Jeśli chodzi o odczytywanie istniejących arkuszy kalkulacyjnych, samouczek dotyczący czytnika Excel w języku C# obejmuje typowe scenariusze importu. Możesz również zapoznać się z instrukcją tworzenia nowego skoroszytu Excel od podstaw dla projektów, które wymagają programowego tworzenia plików zamiast korzystania z szablonów.

Często Zadawane Pytania

Jak mogę eksportować dane do Excela w aplikacjach Blazor Server?

Możesz użyć IronXL do eksportowania danych do Excela w aplikacjach Blazor Server. IronXL pozwala tworzyć, formatować i pobierać pliki Excel bezpośrednio z serwera bez konieczności korzystania z pakietu Microsoft Office.

Czy muszę mieć zainstalowany pakiet Microsoft Office, aby korzystać z IronXL w Blazorze?

Nie, nie musisz mieć zainstalowanego pakietu Microsoft Office. IronXL pozwala na obsługę plików Excel w aplikacjach Blazor Server niezależnie od pakietu Microsoft Office.

Czy mogę formatować pliki Excel za pomocą IronXL w aplikacjach Blazor?

Tak, IronXL udostępnia narzędzia do formatowania plików Excel, umożliwiające dostosowanie wyglądu danych bezpośrednio z aplikacji Blazor Server.

Czy IronXL jest kompatybilny z aplikacjami Blazor Server?

Tak, IronXL płynnie integruje się z aplikacjami Blazor Server, umożliwiając łatwy eksport i obsługę plików Excel.

Jakie są zalety korzystania z IronXL do eksportu do Excela w Blazorze?

IronXL oferuje prosty sposób tworzenia i edycji plików Excel bez konieczności korzystania z pakietu Office, co czyni go wydajnym rozwiązaniem do eksportowania danych w aplikacjach Blazor.

Czy IronXL może obsługiwać duże pliki Excel w aplikacjach Blazor Server?

Tak, IronXL został zaprojektowany do wydajnej obsługi dużych plików Excel w aplikacjach Blazor Server.

Jakie typy plików Excel mogę tworzyć za pomocą IronXL w aplikacji Blazor?

Dzięki IronXL możesz tworzyć różne typy plików Excel, w tym XLSX, XLS i CSV, bezpośrednio w swojej aplikacji Blazor.

Czy można pobierać pliki Excel z aplikacji Blazor Server za pomocą IronXL?

Tak, IronXL obsługuje pobieranie plików Excel bezpośrednio z aplikacji Blazor Server, zapewniając płynne działanie dla użytkowników końcowych.

W jaki sposób IronXL poprawia funkcjonalność eksportu do Excela w Blazorze w porównaniu z innymi rozwiązaniami?

IronXL upraszcza proces eksportowania plików Excel w Blazorze, eliminując potrzebę korzystania z pakietu Microsoft Office i integrując się bezpośrednio z aplikacją serwerową.

Dlaczego IronXL jest dobrym wyborem dla programistów Blazor?

IronXL to dobry wybór dla programistów Blazor, ponieważ oferuje solidne możliwości obsługi Excela, nie wymaga instalacji pakietu Office i łatwo integruje się z aplikacjami Blazor Server.

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie