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 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

Dodaj ten skrypt do 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 do Excela w języku 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żna tworzyć nowe skoroszyty i arkusze za pomocą jednego wywołania metody, stosować stylizowane nagłówki, wypełniać wiersze danymi z dowolnego źródła oraz osadzać formuły programu Excel, takie jak =D2*0.15. Wywołanie AutoSizeColumn zapewnia, że kolumny są wystarczająco szerokie, aby poprawnie wyświetlać ich 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ę pod adresem 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 wyłącza przycisk podczas generowania, zapobiegając powielaniu żądań. Owijka DotNetStreamReference obsługuje wydajny strumień binarny z strumienia pamięci .NET do funkcji JavaScript — unikając dużych ciągów base64, które zwiększałyby rozmiar ładunku. Nazwy plików z sygnaturą czasową, takie jak SalesReport_20260228.xlsx, pozwalają na uporządkowanie pobranych plików bez dodatkowej konfiguracji.

Po przejściu do /excel-export w przeglądarce ładuje się strona pulpitu nawigacyjnego z przyciskiem eksportu:

Eksport z Blazor do Excela: Kompletny przewodnik z wykorzystaniem IronXL w C#: Obraz 1 – Przykładowa strona Blazor

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

Eksport z Blazor do Excela: Kompletny przewodnik z wykorzystaniem 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 warunkówego, wielu arkuszy lub walidacji danych. IronXL obsługuje wszystkie te technologie natywnie.

Formatowanie warunkówe 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 warunkówego 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.

Eksport z Blazora do Excela: Kompletny przewodnik z wykorzystaniem IronXL w C#: Obraz 3 – Przykładowy wynik 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, przechwytując Exception i ponownie rzucając jako InvalidOperationException("Failed to generate sales report", ex). W komponencie Blazor należy przechwycić InvalidOperationException i wyświetlić przyjazny dla użytkownika komunikat bez ujawniania szczegółów wewnętrznych. Zarejestruj wyjątek wewnętrzny za pomocą ILogger<t> wstrzykniętego do konstruktora usługi, aby zespół programistów mógł prześledzić awarie aż do konkretnej operacji w 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. Aby uzyskać więcej wskazówek dotyczących tworzenia usług testowalnych w .NET, dokumentacja Microsoft dotycząca wstrzykiwania zależności wyjaśnia, jak rejestrować i rozwiązywać usługi o ograniczonym zakresie, co jest dokładnie tym samym wzorcem, który został tutaj użyty w 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() programu IronXL zapisuje dane bezpośrednio do strumienia wyjściowego bez konieczności wczytywania całego pliku do tablicy bajtów, co pozwala ograniczyć zużycie pamięci w przypadku dużych skoroszytów. Aby uzyskać dodatkowe wskazówki dotyczące wydajności, zapoznaj się z artykułem na temat odczytu i zapisu dużych plików Excel za pomocą 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 jawnie ustawić format liczb, IronXL udostępnia oba elementy jako właściwości obiektu 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 odczytywać i zapisywać wiele formatów 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.

Firma Microsoft udostępnia przydatne materiały pomocnicze dotyczące formatów plików OOXML, które mogą okazać się przydatne w przypadku konieczności zrozumieniuiuiuiuia wewnętrznej struktury plików .xlsx podczas debugowania nieoczekiwanych wyników. 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 wymagańa jest licencja wdrożeniowa.

Bezpłatną wersję próbną można pobrać bezpośrednio z NuGet — do rozpoczęcia nie jest wymagańa 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.

Jordi Bardia
Inżynier oprogramowania
Jordi jest najbardziej biegły w Pythonie, C# i C++. Kiedy nie wykorzystuje swoich umiejętności w Iron Software, programuje gry. Dzieląc odpowiedzialność za testowanie produktów, rozwój produktów i badania, Jordi wnosi ogromną wartość do ciągłej poprawy produktów. Różnorodne doświadczenia ...
Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie