EPPlus は Microsoft Office の依存なしに Excel ファイルを操作できる強力なライブラリであり、.NET Core 環境でも広く利用されています。
まず、NuGet から EPPlus.Core(例:バージョン 1.5.4)をインストールします。
以下は、任意のデータリストを Excel に変換し、カスタムヘッダー(英語フィールド名 → 日本語表示)を適用して MemoryStream として返す汎用ヘルパークラスです。
using OfficeOpenXml;
using System.Collections.Generic;
using System.IO;
namespace Common
{
public class ExcelExporter
{
public static MemoryStream GenerateExcel<T>(List<T> records, Dictionary<string, string> columnMappings = null)
{
using (var excelPackage = new ExcelPackage())
{
var sheet = excelPackage.Workbook.Worksheets.Add("Data");
sheet.Cells.LoadFromCollection(records, true);
if (columnMappings != null)
{
int lastColumn = sheet.Dimension?.End.Column ?? 0;
for (int colIndex = 1; colIndex <= lastColumn; colIndex++)
{
var currentHeader = sheet.Cells[1, colIndex]?.Value?.ToString();
if (!string.IsNullOrEmpty(currentHeader) && columnMappings.TryGetValue(currentHeader, out var japaneseLabel))
{
sheet.Cells[1, colIndex].Value = japaneseLabel;
}
}
}
return new MemoryStream(excelPackage.GetAsByteArray());
}
}
}
}
この実装では、オブジェクトのプロパティ名が英語であるため、Dictionary<string, string> を使って日本語のカラム見出しに置き換えています。
次に、ASP.NET Core MVC の API コントローラー内でこのヘルパーを使用してファイルを返す例を示します。
[HttpGet("export")]
public IActionResult ExportTradeRecords([FromQuery] TradeRecordQuery query, [FromHeader] string authorization)
{
// 業務ロジック: 全件取得用にページングを調整
query.PageIndex = 1;
query.PageSize = int.MaxValue;
var result = _tradeService.FetchRecords(query);
if (!result.IsSuccess)
throw new InvalidOperationException(result.ErrorMessage);
var exportModels = result.Items.Select(x => new TradeRecordDto
{
TransactionTime = x.TransactionTime,
ProductName = x.ProductName,
Category = x.Category,
AccountId = x.AccountId,
Amount = x.Amount,
Type = x.Type,
Status = x.Status
}).ToList();
var headerMap = new Dictionary<string, string>
{
{ "TransactionTime", "取引日時" },
{ "ProductName", "商品名" },
{ "Category", "カテゴリ" },
{ "AccountId", "アカウントID" },
{ "Amount", "金額(円)" },
{ "Type", "取引種別" },
{ "Status", "ステータス" }
};
var fileName = $"{DateTime.Now:yyyyMMddHHmmssfff}.xlsx";
var excelStream = ExcelExporter.GenerateExcel(exportModels, headerMap);
Response.Headers["Content-Disposition"] =
new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{ FileName = fileName }.ToString();
return File(excelStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
レスポンスヘッダーに Content-Disposition を設定することで、クライアント側で自動的にファイルダウンロードがトリガーされます。ファイル名にはタイムスタンプを含めることで重複を回避できます。