フッターコンテンツにスキップ
IRONXLの使用

IronXLを使用してBlazorで Excel ファイルをエクスポートする方法

データをExcelにエクスポートすることは、売上レポート、在庫リスト、顧客請求書などを作成する場合でも、ほぼすべてのBlazor Webアプリケーションで必要となる機能です。Blazor Blazorアプリケーションでは、Microsoft Officeを必要とせずにこれを確実に実現するのは、困難に感じられるかもしれません。 IronXLを使えば簡単です。Officeのインストールは不要で、サーバーから直接Excelファイルを作成、フォーマット、ダウンロードできます。 このガイドでは、 IronXLを使用してBlazorで実運用可能なExcelエクスポート機能を構築する手順を、プロジェクト設定やサービス設計から、高度な書式設定や複数シートレポートまで、順を追って説明します。

BlazorサーバープロジェクトでIronXLをセットアップするにはどうすればよいですか?

エクスポートロジックを記述する前に、 Blazor ServerプロジェクトにIronXLを追加し、ブラウザ側のダウンロードヘルパーを設定する必要があります。

Blazorサーバープロジェクトの作成

まず、Visual Studio 2022以降で.NET 10をターゲットとした新しいBlazor Serverプロジェクトを作成します。プロジェクトの準備ができたら、 NuGetパッケージマネージャーコンソールを使用してIronXLをインストールします。

Install-Package IronXl.Excel

IronXLは.NET 6以降に対応しているため、既存のBlazorプロジェクトはフレームワークをアップグレードすることなくIronXLを採用できます。 NuGet UI や CLI などの別のインストール方法については、 IronXL のインストール ガイドを参照してください。

JavaScriptダウンロードヘルパーを追加する

Blazor Serverはサーバー側で動作するため、ファイルのダウンロードをトリガーするには小さなJavaScriptブリッジが必要です。 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

このスクリプトを _Host.cshtml ファイル (または.NET 8 以降では App.razor) に含めてください。

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

この関数は、 Blazorからのバイトストリームを一時的なブロブURLに変換し、ブラウザのダウンロードをトリガーした後、メモリリークを防ぐためにURLオブジェクトをクリーンアップします。 意図的に最小限の構成に抑えており、主要な処理はサーバー側のC#で行われる。

今IronXLを始めましょう。
green arrow pointer

C#でExcelエクスポートサービスを作成するにはどうすればよいですか?

Excel生成処理をRazorコンポーネントから分離することで、コードのテスト容易性と複数ページにわたる再利用性が向上します。 以下のパターンは、 IronXLを専用のサービスクラス内にラップするものです。

ExcelExportServiceの構築

新しいファイル 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

サービスの登録

Program.cs の DI コンテナにサービスを追加します。

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

このサービスは、 IronXLのいくつかの重要な機能を示しています。 単一のメソッド呼び出しで新しいワークブックとワークシートを作成し、スタイル付きヘッダーを適用し、任意のデータソースから行を入力し、=D2*0.15 のようなExcel 数式を埋め込むことができます。 AutoSizeColumn 呼び出しは、データの長さに関係なく、列がコンテンツを正しく表示できる十分な幅であることを保証します。 その他の書式設定オプションについては、セルスタイルガイドを参照してください。

BlazorコンポーネントからExcelファイルのダウンロードをトリガーするにはどうすればよいですか?

サービスが確立されたら、そのサービスを呼び出し、結果として得られたバイト列をブラウザに渡すRazorコンポーネントが必要になります。

Razorコンポーネントの作成

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

コンポーネントの機能

isExporting フラグは生成中にボタンを無効にし、重複リクエストを防ぎます。 DotNetStreamReference ラッパーは、 .NETメモリ ストリームからJavaScript関数への効率的なバイナリ ストリーミングを処理し、ペイロード サイズを膨張させる大きな base64 文字列を回避します。SalesReport_20260228.xlsx のようなタイムスタンプ付きファイル名により、追加の設定なしでダウンロードを整理できます。

ブラウザで/excel-exportにアクセスすると、エクスポートボタンが表示されたダッシュボードページが読み込まれます。

 BlazorExcel へのエクスポート: C# でIronXLを使用した完全ガイド: 画像 1 - サンプルBlazorページ

ボタンをクリックするとスプレッドシートが生成され、ブラウザが自動的にファイルをダウンロードします。

 BlazorExcel へのエクスポート: C# でIronXLを使用する完全ガイド: 画像 2 - Excel ファイルにエクスポートされたデータ

Excelのエクスポートに適用できる高度な書式設定にはどのようなものがありますか?

基本的なデータエクスポートは多くのユースケースに対応できますが、実際のアプリケーションでは、条件付き書式設定、複数のワークシート、またはデータ検証が必要になることがよくあります。 IronXLはこれらすべてをネイティブにサポートしています。

在庫レポートの条件付き書式設定

以下のサービスは、在庫が少ない商品を赤色で強調表示します。これは、倉庫管理や在庫管理アプリケーションでよく求められる機能です。

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は、データ生成時にデータ値に基づいてセルレベルの書式設定を適用します。また、条件付き書式設定ルールを宣言的に適用したり、同じワークブック内で複数のワークシートを管理したりすることも可能です。例えば、現在の在庫状況を表示するシートと、過去の注文履歴を表示するシートなどです。

複数のワークシートを単一のエクスポートに追加する

データを論理的なシートに分割することで、個別のダウンロードを必要とせずに可読性が向上します。

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

ワークブックのプロパティ、範囲操作、グラフのサポートなど、API の完全なリファレンスについては、 IronXL API ドキュメントを参照してください。

 BlazorExcel へのエクスポート: C# でIronXLを使用する完全ガイド: 画像 3 - 高度な機能の例出力

エラーや大規模データセットを効率的に処理するにはどうすればよいでしょうか?

データセットが大きい場合、Excelのエクスポート操作はエラーメッセージを表示せずに失敗したり、パフォーマンスが低下したりすることがあります。 以下のパターンは、両方の懸念事項に対応しています。

サービス層におけるエラー処理

生成ロジックを(コンポーネントではなく)サービス内にラップすることで、すべての呼び出し元でエラー処理の一貫性を保つことができます。 推奨されるパターンは、 IronXLの例外を伝播させた後、どのレポートが失敗したかに関するコンテキストを含むドメイン固有の例外でそれらをラップすることです。

GenerateSalesReport のワークブック生成の周りに try/catch ブロックを配置し、Exception をキャッチして InvalidOperationException("Failed to generate sales report", ex) として再スローします。 Blazorコンポーネントで、InvalidOperationException をキャッチし、内部の詳細を公開せずにユーザーフレンドリーなメッセージを表示します。 サービスコンストラクタに注入された ILogger<t> を使用して内部例外をログに記録することで、開発チームが障害を特定のワークブック操作まで遡って追跡できるようにします。 例外メッセージをそのままエンドユーザーに表示してはいけません。ファイルパス、メモリアドレス、スタックトレースなどは、サーバーの内部構造を露呈する可能性があります。

Blazorにおける構造化エラーログの記述に関するガイダンスについては、Microsoft の公式ドキュメントにあるエラー処理のベストプラクティスを参照してください。 .NETでテスト可能なサービスを構築する方法についての詳細は、 Microsoft の依存性注入ドキュメントで、スコープ付きサービスを登録および解決する方法が説明されています。これは、ExcelExportService で使用されているパターンとまったく同じです。

大規模データセットのパフォーマンスに関する考慮事項

数千行を超えるデータセットの場合は、以下の方法を検討してください。

Excelエクスポートのパフォーマンス戦略
戦略 使用時期 IronXLサポート
応答に直接ストリームする Files >10 MB `workbook.ToStream()`
エクスポート前にデータをページ分割する フィルターを使用したUI駆動型エクスポート ワークブックを作成する前にサービスに適用してください
バックグラウンドジョブ + ダウンロードリンク Reports taking >5 seconds SignalRまたはポーリングと組み合わせる
大きなシートでは列の自動サイズ調整を無効にする Sheets with >500 rows 代わりに固定列幅を設定してください

IronXL の ToStream() メソッドは、ファイル全体を最初にバイト配列に読み込むことなく出力ストリームに直接書き込むため、大きなワークブックのメモリ使用量を低く抑えることができます。 パフォーマンスに関する詳細なガイダンスについては、 "IronXLを使用した大規模な Excel ファイルの読み書き"を参照してください。

IronXLは他にどのようなExcel機能をサポートしていますか?

IronXLは、基本的なエクスポート機能に加え、実際のレポート作成要件に対応する幅広いExcel機能を提供します。

数式、名前付き範囲、および数値書式設定

Excelの数式は、セルに直接入力するのと同じ構文で埋め込むことができます。 IronXLは読み込み時に数式を評価するため、生成されたファイルの利用者はスプレッドシートを開くとすぐに計算結果を確認できます。 名前付き範囲を使用すると、数式がより読みやすくなり、長期的に保守しやすくなります。

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

名前付き範囲を定義し数値形式を明示的に設定するために、 IronXLは範囲オブジェクトのプロパティとして両方を公開しています。 これにより、Excelが通貨値をプレーンテキストとして扱うことを防ぎます。これは、値を文字列として保存するデータベースから財務データをエクスポートする際によく発生する問題です。

サポートされているExcelファイル形式

IronXL は、.csv、および .tsv を含む複数の Excel フォーマットを読み書きできます。 フォーマットは保存時に決定されるため、わずかなパラメータ変更で同じサービス クラスが Excel と 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 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

この柔軟性は、ERPプラットフォームやデータウェアハウスなどの下流システムが特定のファイル形式を要求するような統合において重要となる。 IronXLと他のExcelライブラリの機能比較については、 IronXLの機能ページをご覧ください。

予期しない出力のデバッグ時に .xlsx ファイルの内部構造を理解する必要がある場合は、Microsoft がOOXML ファイル形式を理解するための優れたリファレンスを提供しています。 IronXL用のNuGetパッケージは、 NuGetにも掲載されており、完全なバージョン履歴と互換性に関する注記も記載されています。

BlazorプロジェクトでIronXLを使い始めるにはどうすればよいですか?

IronXLは、時間制限なく開発やテストを行うことができる無料の開発ライセンスで提供されています。 本番環境で使用する場合は、導入ライセンスが必要です。

NuGetから無料トライアル版を直接ダウンロードできます。利用開始にあたって登録は不要です。 導入準備が整ったら、 IronXLのライセンスオプションを確認し、アプリケーションの規模に合ったプランを選択してください。

IronXLは、 Blazor Server、 Blazor WebAssembly(サーバーレンダリング)、 ASP.NET Core MVC、コンソールアプリケーション、Windowsデスクトップアプリなど、主要な.NETアプリケーションタイプすべてに対応しています。ライブラリは.NET Standard 2.0をターゲットとしているため、 .NET Framework 4.6.2から.NET 10までのすべてのサポート対象.NETバージョンと互換性があります。プロジェクトでPDF生成も必要な場合は、 IronPDFがIronXLと競合することなく統合されるため、同じサービスレイヤーからExcelまたはPDF形式でデータをエクスポートできます。

Blazor固有の例をさらに詳しく知りたい場合は、 Blazor ExcelエクスポートチュートリアルASP.NET Coreエクスポートガイドを参照してください。 既存のスプレッドシートを読み込む方法については、 C# Excelリーダーのチュートリアルで一般的なインポートシナリオを解説しています。 テンプレートからではなく、プログラムによってファイルを作成する必要があるプロジェクトのために、Excelワークブックをゼロから作成する方法を確認することもできます。

よくある質問

Blazor Server アプリでデータを Excel にエクスポートするにはどうすればよいですか?

IronXLを使用すると、 Blazor ServerアプリでデータをExcelにエクスポートできます。IronXLを使用すると、Microsoft Officeを必要とせずに、サーバーから直接Excelファイルを作成、フォーマット、ダウンロードできます。

BlazorでIronXLを使用するにはMicrosoft Officeがインストールされている必要がありますか?

いいえ、Microsoft Office をインストールする必要はありません。IronXLを使用すると、 Blazor Server アプリで Microsoft Office に依存せずに Excel ファイルを処理できます。

BlazorアプリケーションでIronXLを使用して Excel ファイルをフォーマットできますか?

はい、 IronXL には Excel ファイルをフォーマットするためのツールが用意されており、 Blazor Server アプリから直接データの外観をカスタマイズできます。

IronXL はBlazor Server アプリケーションと互換性がありますか?

はい、 IronXL はBlazor Server アプリケーションとシームレスに統合され、Excel ファイルの簡単なエクスポートと処理が可能になります。

BlazorでのExcelエクスポートにIronXLを使用する利点は何ですか?

IronXL は、Office を必要とせずに Excel ファイルを簡単に作成および操作する方法を提供するため、 Blazorアプリでデータをエクスポートするための効率的なソリューションとなります。

IronXL はBlazor Server アプリで大きな Excel ファイルを処理できますか?

はい、 IronXLはBlazor Server アプリケーション内で大きな Excel ファイルを効率的に処理するように設計されています。

BlazorアプリでIronXLを使用して作成できる Excel ファイルの種類は何ですか?

IronXL を使用すると、XLSX、XLS、CSV などのさまざまな種類の Excel ファイルをBlazorアプリケーション内で直接作成できます。

IronXLを使用してBlazor Server アプリから Excel ファイルをダウンロードすることは可能ですか?

はい、 IronXL はBlazor Server アプリから Excel ファイルを直接ダウンロードすることをサポートしており、エンドユーザーにシームレスなエクスペリエンスを提供します。

IronXL は他のソリューションと比較して、 Blazorの Excel エクスポート機能をどのように改善しますか?

IronXL は、Microsoft Office を必要とせず、サーバー アプリケーションと直接統合することで、 Blazorで Excel ファイルをエクスポートするプロセスを簡素化します。

Blazor開発者にとってIronXL が最適な選択肢となる理由は何ですか?

IronXL は、強力な Excel 処理機能を備え、Office のインストールを必要とせず、 Blazor Server アプリに簡単に統合できるため、 Blazor開発者にとって最適な選択肢です。

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

アイアンサポートチーム

私たちは週5日、24時間オンラインで対応しています。
チャット
メール
電話してね