フッターコンテンツにスキップ
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生成処理を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

サービスの登録

サービスをDIコンテナに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

このサービスは、 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フラグは、生成中にボタンを無効にし、重複したリクエストを防ぎます。 SalesReport_20260228.xlsxのようなタイムスタンプ付きファイル名は、追加の設定なしでダウンロードを整理します。

ブラウザで/excel-exportに移動すると、エクスポートボタン付きのダッシュボードページが読み込まれます。

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

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

BlazorからExcelへエクスポート: IronXLを使用した完全ガイド(C#): 画像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 ドキュメントを参照してください。

BlazorからExcelへエクスポート: IronXLを使用した完全ガイド(C#): 画像3 - 高度な機能のサンプル出力

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

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

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

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

ワークブック生成に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は、.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の機能ページをご覧ください。

Microsoftは、.xlsxファイルの内部構造を理解する必要がある場合に予期しない出力のデバッグ時に、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
テクニカルライター

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

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

アイアンサポートチーム

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