IRONXLの使用 IronXLを使用してBlazorで Excel ファイルをエクスポートする方法 カーティス・チャウ 更新日:2026年3月1日 IronXL をダウンロード NuGet ダウンロード DLL ダウンロード 無料トライアル LLM向けのコピー LLM向けのコピー LLM 用の Markdown としてページをコピーする ChatGPTで開く このページについてChatGPTに質問する ジェミニで開く このページについてGeminiに問い合わせる Grokで開く このページについてGrokに質問する 困惑の中で開く このページについてPerplexityに問い合わせる 共有する Facebook で共有 Xでシェア(Twitter) LinkedIn で共有 URLをコピー 記事をメールで送る データを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を始めましょう。 無料で始める 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にアクセスすると、エクスポートボタンが表示されたダッシュボードページが読み込まれます。 ボタンをクリックするとスプレッドシートが生成され、ブラウザが自動的にファイルをダウンロードします。 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 ドキュメントを参照してください。 エラーや大規模データセットを効率的に処理するにはどうすればよいでしょうか? データセットが大きい場合、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ボットを作成したりして、技術に対する愛情と創造性を組み合わせています。 関連する記事 更新日 2026年3月1日 ASP .NET C# で Excel ファイルをダウンロード: XLSX、CSV などにデータをエクスポート C#とIronXLを使用して、 ASP.NET CoreでExcelファイルをダウンロードします。MVCコントローラーからMemoryStreamとFile()を使用して、XLSX、CSV、XML形式でデータをエクスポートします。コード例も含まれています。 詳しく読む 更新日 2026年2月27日 StreamReader の代わりに C# で Excel ファイルを読み取る方法 StreamReader が Excel ファイルを読み取れない理由と、 IronXL を使用して C# .NETのディスクまたはメモリ ストリームから XLSX および XLS ワークブックを読み込む方法について説明します。 詳しく読む 更新日 2026年3月1日 IronXLを使用して C# で Excel ファイルを生成する方法 IronXLを使用して C# で Excel ファイルを生成する方法を学びます。基本的なスプレッドシートの作成、書式設定、数式、および Office に依存せずにデータベース統合について説明します。 詳しく読む Excel で相互運用性なしで C# を使ってピボット テーブルを作成する方法StreamReader の代わりに C# で...
更新日 2026年3月1日 ASP .NET C# で Excel ファイルをダウンロード: XLSX、CSV などにデータをエクスポート C#とIronXLを使用して、 ASP.NET CoreでExcelファイルをダウンロードします。MVCコントローラーからMemoryStreamとFile()を使用して、XLSX、CSV、XML形式でデータをエクスポートします。コード例も含まれています。 詳しく読む
更新日 2026年2月27日 StreamReader の代わりに C# で Excel ファイルを読み取る方法 StreamReader が Excel ファイルを読み取れない理由と、 IronXL を使用して C# .NETのディスクまたはメモリ ストリームから XLSX および XLS ワークブックを読み込む方法について説明します。 詳しく読む
更新日 2026年3月1日 IronXLを使用して C# で Excel ファイルを生成する方法 IronXLを使用して C# で Excel ファイルを生成する方法を学びます。基本的なスプレッドシートの作成、書式設定、数式、および Office に依存せずにデータベース統合について説明します。 詳しく読む