C#でExcel操作する方法|読み書き・出力・ライブラリ選びをサンプルコード付きで解説

はじめに

C#でExcel操作を行う場面は、業務システムや社内ツールの開発で非常によくあります。たとえば、Excelファイルから受注データを読み込む、集計結果をExcelに出力する、テンプレートを使って請求書や見積書を作成する、といった処理です。

C#でExcelを扱う方法には、Microsoft.Office.Interop.Excelを使ってExcel本体を操作する方法と、ClosedXML、EPPlus、NPOI、Open XML SDKなどのライブラリを使ってExcelファイルを直接読み書きする方法があります。ClosedXMLはExcel 2007以降の.xlsxや.xlsmを読み書きできる.NETライブラリとして公開されており、OpenXML APIを扱いやすくすることを目的としています。

この記事では、C#でExcel操作を始めたい人に向けて、読み込み、書き込み、Excel出力、ライブラリ選び、よくあるエラー、実務での設計ポイントまで、サンプルコード付きで解説します。

1. C#でExcel操作する前に知っておきたい基本

1-1. C#でExcel操作すると何ができるのか

C#でExcel操作を実装すると、手作業で行っていたExcelファイルの作成や更新をプログラムから自動化できます。

代表的には、次のような処理が可能です。

処理内容
読み込みExcelファイルのセル、行、列、シートの値を取得する
書き込みセルに文字列、数値、日付、数式を書き込む
出力DBやList、DataTableの内容をExcelファイルとして保存する
帳票作成請求書、見積書、納品書、集計表などをExcel形式で作成する
装飾背景色、罫線、列幅、表示形式、フィルターなどを設定する
更新既存のExcelファイルを開いて一部の値を変更する

C#でExcelを操作できるようになると、業務アプリ、Webアプリ、バッチ処理、データ移行ツール、帳票出力機能など、さまざまな開発に応用できます。

1-2. Excel操作でよくある用途|読み込み・書き込み・帳票出力

C#のExcel操作で特によく使われる用途は、読み込み、書き込み、帳票出力の3つです。

読み込みは、ユーザーが作成したExcelファイルをアプリケーションに取り込む処理です。たとえば、商品マスタ、社員一覧、受注データ、在庫データなどをExcelから読み取ってデータベースに登録します。

書き込みは、プログラムで作成したデータをExcelファイルに保存する処理です。検索結果、集計結果、ログ、レポートなどをExcel形式で出力する場合に使います。

帳票出力は、あらかじめ用意したExcelテンプレートに値を差し込んで、請求書や見積書などの書類を作成する処理です。セルの書式やレイアウトをExcel側で作っておけるため、見た目を整えやすいのが特徴です。

1-3. Excelファイル形式の違い|xlsx・xls・csvの特徴

C#でExcel操作を行う前に、ファイル形式の違いを理解しておきましょう。

形式特徴主な用途
xlsxExcel 2007以降の標準形式。Open XML形式通常のExcel出力、読み書き
xlsExcel 97-2003の古い形式古いシステムとの連携
xlsmマクロ付きExcelファイルマクロを含むブックの編集
csvカンマ区切りのテキストファイル単純なデータ出力、他システム連携

現在のC#開発で新規にExcel出力するなら、基本的には.xlsx形式を選ぶのがおすすめです。xlsxは多くのライブラリで扱いやすく、セルの書式、複数シート、数式、フィルターなども利用できます。

一方、csvはExcel専用形式ではなくテキストファイルです。軽量で扱いやすい反面、背景色、罫線、複数シート、セル結合、数式の保存などはできません。

1-4. Excel操作にExcel本体は必要か

C#でExcel操作をする場合、Excel本体が必要かどうかは選ぶ方法によって異なります。

Microsoft.Office.Interop.Excelを使う場合は、ExcelアプリケーションをCOM経由で操作するため、実行環境にExcel本体が必要です。一方、ClosedXML、EPPlus、NPOI、Open XML SDKなどを使う場合は、Excelファイルを直接読み書きするため、基本的にExcel本体は不要です。

特にWebアプリやサーバー環境では、Excel本体を起動して操作する方式は避けるべきです。Microsoftは、ASP.NET、DCOM、NT Servicesなどの非対話型クライアントやコンポーネントからOfficeアプリケーションを自動化することを推奨・サポートしていないと説明しています。

2. C#でExcel操作する主な方法

2-1. Microsoft.Office.Interop.Excelを使う方法

Microsoft.Office.Interop.Excelは、C#からExcelアプリケーションそのものを操作する方法です。Excelを開く、セルに値を入れる、保存する、印刷する、PDF出力する、といった操作をExcel本体に対して実行できます。

簡単な例は次のとおりです。

C#
using Excel = Microsoft.Office.Interop.Excel;

var excel = new Excel.Application();
var workbook = excel.Workbooks.Add();
var worksheet = (Excel.Worksheet)workbook.Worksheets[1];

worksheet.Cells[1, 1] = "商品名";
worksheet.Cells[1, 2] = "金額";
worksheet.Cells[2, 1] = "ノートPC";
worksheet.Cells[2, 2] = 120000;

workbook.SaveAs(@"C:\temp\sample.xlsx");

workbook.Close();
excel.Quit();

InteropはExcel本体の機能を使えるため、マクロ、印刷、PDF変換などExcel依存の処理には向いています。ただし、Excelのインストールが必要で、プロセス解放漏れやサーバー環境での不安定さに注意が必要です。

そのため、Windowsデスクトップアプリで、ユーザーのPC上にExcelがあり、Excel本体の機能を使いたい場合に限定して検討するのがよいでしょう。

2-2. ClosedXMLを使う方法

ClosedXMLは、C#でExcelファイルを簡単に読み書きしたい場合に使いやすいライブラリです。.xlsxや.xlsmに対応しており、OpenXML APIを直接扱うよりも直感的なコードでExcel操作ができます。

インストールはNuGetで行います。

Bash
dotnet add package ClosedXML

Excelファイルを作成する基本コードは次のとおりです。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";
worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

workbook.SaveAs("sales.xlsx");

ClosedXMLは、初心者にも扱いやすく、業務アプリのExcel読み込み・書き込み・帳票出力に向いています。特別な理由がなければ、C#のExcel操作ではClosedXMLから検討するとよいでしょう。

2-3. EPPlusを使う方法

EPPlusは、Excelファイルの読み書き、スタイル設定、数式、グラフなどに対応した高機能なライブラリです。EPPlus 8も.NET Framework/Core向けのスプレッドシートライブラリとして提供されています。

インストールは次のように行います。

Bash
dotnet add package EPPlus

基本的な出力例は次のとおりです。

C#
using OfficeOpenXml;

ExcelPackage.License.SetNonCommercialPersonal("Your Name");

using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("売上");

worksheet.Cells[1, 1].Value = "商品名";
worksheet.Cells[1, 2].Value = "金額";
worksheet.Cells[2, 1].Value = "ノートPC";
worksheet.Cells[2, 2].Value = 120000;

package.SaveAs(new FileInfo("sales.xlsx"));

EPPlusは機能が豊富ですが、バージョン5以降はPolyform Noncommercialライセンスと商用ライセンスのデュアルライセンスです。個人・非商用利用は無料ですが、商用利用では商用ライセンスが必要とされています。

2-4. NPOIを使う方法

NPOIは、JavaのApache POIを.NET向けに移植したライブラリです。Office 2003/2007形式のファイルを読み書きできるライブラリとして公開されています。

インストールは次のとおりです。

Bash
dotnet add package NPOI

xlsxファイルを作成する例です。

C#
using NPOI.XSSF.UserModel;

var workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet("売上");

var header = sheet.CreateRow(0);
header.CreateCell(0).SetCellValue("商品名");
header.CreateCell(1).SetCellValue("金額");

var row = sheet.CreateRow(1);
row.CreateCell(0).SetCellValue("ノートPC");
row.CreateCell(1).SetCellValue(120000);

using var stream = new FileStream("sales.xlsx", FileMode.Create, FileAccess.Write);
workbook.Write(stream);

NPOIの特徴は、xlsxだけでなく古いxls形式も扱える点です。既存システムでxls形式を読み書きする必要がある場合は、NPOIが候補になります。

2-5. Open XML SDKを使う方法

Open XML SDKは、Microsoftが提供するOpen XML形式のOfficeドキュメントを操作するためのSDKです。Excel、Word、PowerPointなどのファイルをプログラムで作成・編集できます。Microsoft Learnでは、Open XML SDKを使ってSpreadsheetML要素に対応する厳密に型指定されたクラスでドキュメント構造やコンテンツを作成できると説明されています。

インストールは次のとおりです。

Bash
dotnet add package DocumentFormat.OpenXml

Open XML SDKは低レベルな操作に向いていますが、Excelのセルやスタイルを簡単に扱いたい場合はコード量が多くなりがちです。大量データ処理や細かいOpen XML制御が必要な場合には有力ですが、初心者が通常のExcel出力を実装するなら、ClosedXMLなどの高水準ライブラリのほうが扱いやすいでしょう。

2-6. Excel操作ライブラリを使わずCSVで出力する方法

単純な一覧データを出力するだけなら、Excelライブラリを使わずCSVで出力する方法もあります。

C#
using System.Text;

var lines = new List<string>
{
"商品名,金額",
"ノートPC,120000",
"マウス,3000"
};

File.WriteAllLines("sales.csv", lines, new UTF8Encoding(true));

CSVは実装が簡単で、ファイルサイズも軽く、他システムとの連携にも向いています。ただし、複数シート、セル結合、罫線、背景色、列幅、表示形式などは表現できません。

「一覧データを渡すだけ」ならCSV、「Excelらしい帳票や書式付きレポートを出したい」ならxlsxを選ぶとよいでしょう。

3. C#のExcel操作ライブラリの選び方

3-1. 初心者や業務アプリで使いやすいライブラリ

初心者や業務アプリで使いやすいのはClosedXMLです。理由は、APIが直感的で、セルの読み書き、シート操作、スタイル設定、テーブル出力などを短いコードで書けるためです。

たとえば、A1セルに値を入れるだけなら次のように書けます。

C#
worksheet.Cell("A1").Value = "売上レポート";

Open XML SDKのようにXML構造を意識する必要が少なく、Excelの画面操作に近い感覚で実装できます。

3-2. Excelインストール不要で使えるライブラリ

Excel本体をインストールせずにExcelファイルを操作したい場合は、ClosedXML、EPPlus、NPOI、Open XML SDKが候補です。

ライブラリExcel本体
Microsoft.Office.Interop.Excel必要
ClosedXML不要
EPPlus不要
NPOI不要
Open XML SDK不要

サーバー、Docker、Linux、クラウド環境でExcel出力する場合は、Excel本体に依存しないライブラリを選びましょう。

3-3. Webアプリ・サーバー環境で使いやすいライブラリ

ASP.NET CoreなどのWebアプリでは、ClosedXML、EPPlus、NPOI、Open XML SDKのようにExcel本体を起動しないライブラリを使うのが基本です。

InteropはExcelプロセスを起動する方式のため、サーバーで同時リクエストが発生した場合に、プロセスが残る、ロックされる、権限で失敗する、動作が不安定になるといった問題が起こりやすくなります。Microsoftも非対話型環境でのOffice自動化を推奨・サポートしていないため、サーバー側のExcel出力では避けるべきです。

3-4. 大量データ処理に向いているライブラリ

大量データを処理する場合は、メモリ使用量と処理速度を意識する必要があります。

ClosedXMLは使いやすい反面、ブック全体をメモリ上に展開するため、数十万行規模のデータではメモリ消費が大きくなることがあります。大量データでは、NPOIのストリーミング系機能やOpen XML SDKを検討するとよいでしょう。

ただし、実務では「本当にExcelで数十万行を出力すべきか」も検討が必要です。Excelで人が確認する用途なら、件数を絞る、CSVにする、分割ファイルにする、検索条件を必須にするなどの設計も重要です。

3-5. 無料利用・商用利用・ライセンスの注意点

ライブラリを選ぶときは、機能だけでなくライセンスも確認しましょう。

ClosedXMLはGitHubでMIT licenseとして公開されています。 一方、EPPlusはバージョン5以降、非商用向けのPolyform Noncommercialと商用ライセンスのデュアルライセンスで、商用利用には商用ライセンスが必要と説明されています。

ライセンスはバージョンや利用形態によって判断が変わることがあります。会社のシステムで使う場合は、NuGetのパッケージ情報、公式サイト、GitHubのLICENSE、社内ルールを確認してから採用しましょう。

3-6. 迷ったときのおすすめライブラリ比較表

ライブラリ特徴xlsxxlsExcel本体向いている用途
ClosedXML簡単で読みやすい×不要一般的な業務アプリ、帳票出力
EPPlus高機能×不要高度なExcel出力、商用ライセンス前提の開発
NPOIxlsにも対応不要古いxls形式との連携
Open XML SDK低レベル制御×不要大量データ、細かいOpen XML制御
InteropExcel本体を操作必要デスクトップ環境、印刷、PDF変換、マクロ連携
CSV軽量なテキスト××不要単純な一覧データ出力

迷った場合は、まずClosedXMLを検討するとよいでしょう。古いxlsが必要ならNPOI、商用ライセンスを許容して高機能なExcel操作をしたいならEPPlus、大量データや低レベル制御が必要ならOpen XML SDKが候補になります。

4. C#でExcelファイルを読み込む方法

4-1. Excelファイルを開いてシートを取得する

ここからはClosedXMLを使って、C#でExcelファイルを読み込む方法を解説します。

まずはNuGetでClosedXMLをインストールします。

Bash
dotnet add package ClosedXML

Excelファイルを開いて、最初のシートを取得するコードは次のとおりです。

C#
using ClosedXML.Excel;

var filePath = "input.xlsx";

using var workbook = new XLWorkbook(filePath);
var worksheet = workbook.Worksheet(1);

Console.WriteLine(worksheet.Name);

シート名で取得することもできます。

C#
var worksheet = workbook.Worksheet("売上");

シート名が固定されている業務ではシート名指定、ファイルの先頭シートを読むだけならインデックス指定を使うとよいでしょう。

4-2. セルの値を読み込むサンプルコード

セルの値を読み込む基本コードです。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook("input.xlsx");
var worksheet = workbook.Worksheet("売上");

string productName = worksheet.Cell("A2").GetString();
double price = worksheet.Cell("B2").GetDouble();
DateTime orderDate = worksheet.Cell("C2").GetDateTime();

Console.WriteLine(productName);
Console.WriteLine(price);
Console.WriteLine(orderDate);

列番号と行番号で指定することもできます。

C#
var value = worksheet.Cell(2, 1).GetString(); // 2行目、1列目

固定レイアウトのExcelを読む場合は、Cell("A2")のようにセル番地で指定すると分かりやすくなります。一覧データを読む場合は、行番号と列番号でループ処理するほうが便利です。

4-3. 複数行・複数列のデータをループで読み込む

Excelの一覧データを読み込む場合は、最終行と最終列を取得してループします。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook("input.xlsx");
var worksheet = workbook.Worksheet("売上");

var lastRow = worksheet.LastRowUsed().RowNumber();
var lastColumn = worksheet.LastColumnUsed().ColumnNumber();

for (int row = 1; row <= lastRow; row++)
{
for (int col = 1; col <= lastColumn; col++)
{
var value = worksheet.Cell(row, col).GetString();
Console.Write($"{value}\t");
}

Console.WriteLine();
}

1行目がヘッダーの場合は、2行目から読み込みます。

C#
for (int row = 2; row <= lastRow; row++)
{
var productName = worksheet.Cell(row, 1).GetString();
var price = worksheet.Cell(row, 2).GetDouble();

Console.WriteLine($"{productName}: {price}");
}

4-4. ヘッダー行をもとにデータを取得する

実務では、列番号を固定するとExcelの列順変更に弱くなります。そこで、1行目のヘッダー名から列番号を取得する方法が便利です。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook("input.xlsx");
var worksheet = workbook.Worksheet("売上");

var headerMap = worksheet.Row(1)
.CellsUsed()
.ToDictionary(
cell => cell.GetString(),
cell => cell.Address.ColumnNumber
);

var lastRow = worksheet.LastRowUsed().RowNumber();

for (int row = 2; row <= lastRow; row++)
{
var productName = worksheet.Cell(row, headerMap["商品名"]).GetString();
var price = worksheet.Cell(row, headerMap["金額"]).GetDouble();
var orderDate = worksheet.Cell(row, headerMap["受注日"]).GetDateTime();

Console.WriteLine($"{orderDate:yyyy/MM/dd} {productName} {price}");
}

この方法なら、「商品名」「金額」「受注日」の列順が変わっても、ヘッダー名が同じであれば読み込めます。

4-5. 日付・数値・文字列を正しく読み込むポイント

Excelのセルには、見た目の表示形式と内部的な値があります。たとえば、画面上では「2026/06/11」と見えていても、内部的には日付シリアル値として保存されています。

ClosedXMLで型を意識して読み込む場合は、次のようにします。

C#
var cell = worksheet.Cell("A2");

if (cell.TryGetValue<DateTime>(out var dateValue))
{
Console.WriteLine(dateValue.ToString("yyyy/MM/dd"));
}
else
{
Console.WriteLine("日付ではありません");
}

数値も同様です。

C#
var cell = worksheet.Cell("B2");

if (cell.TryGetValue<decimal>(out var amount))
{
Console.WriteLine(amount);
}
else
{
Console.WriteLine("数値ではありません");
}

すべてをGetString()で取得すると実装は簡単ですが、日付や数値の判定、DB登録、集計処理では型変換のミスが起きやすくなります。業務データとして扱う場合は、日付、数値、文字列を明確に分けて読み込みましょう。

4-6. 空白セルや結合セルを扱うときの注意点

空白セルを読み込む場合は、IsEmpty()で判定できます。

C#
var cell = worksheet.Cell("A2");

if (cell.IsEmpty())
{
Console.WriteLine("空白です");
}
else
{
Console.WriteLine(cell.GetString());
}

結合セルは、左上のセルだけに値が入っていることが多いため注意が必要です。たとえば、A1:C1が結合されている場合、値はA1にあり、B1やC1は空のように見えることがあります。

結合セルを含む帳票を読み込む場合は、結合範囲の先頭セルを参照するようにします。

C#
var cell = worksheet.Cell("B1");

if (cell.IsMerged())
{
var mergedRange = cell.MergedRange();
var value = mergedRange.FirstCell().GetString();
Console.WriteLine(value);
}

データ取り込み用のExcelでは、できるだけ結合セルを使わない設計にするのがおすすめです。人間が見る帳票では結合セルが便利ですが、プログラムで読み込むデータとしては扱いにくくなります。

5. C#でExcelファイルに書き込む方法

5-1. 新規Excelファイルを作成する

ClosedXMLで新しいExcelファイルを作成する基本コードです。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";

workbook.SaveAs("output.xlsx");

XLWorkbookがExcelブック、worksheetがシート、Cellがセルを表します。Excelの画面構成と近いため、C#から直感的にExcelを操作できます。

5-2. セルに文字列・数値・日付を書き込むサンプルコード

文字列、数値、日付を書き込む例です。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";
worksheet.Cell("C1").Value = "受注日";

worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;
worksheet.Cell("C2").Value = new DateTime(2026, 6, 11);

worksheet.Cell("B2").Style.NumberFormat.Format = "#,##0";
worksheet.Cell("C2").Style.DateFormat.Format = "yyyy/mm/dd";

workbook.SaveAs("sales.xlsx");

日付や数値を書き込むときは、値だけでなく表示形式も設定すると、Excelで開いたときに見やすくなります。

5-3. DataTableやListのデータをExcelに出力する

DataTableをExcelに出力する例です。

C#
using System.Data;
using ClosedXML.Excel;

var table = new DataTable("売上");
table.Columns.Add("商品名", typeof(string));
table.Columns.Add("金額", typeof(decimal));
table.Columns.Add("受注日", typeof(DateTime));

table.Rows.Add("ノートPC", 120000, new DateTime(2026, 6, 11));
table.Rows.Add("マウス", 3000, new DateTime(2026, 6, 12));

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell(1, 1).InsertTable(table);
worksheet.Columns().AdjustToContents();

workbook.SaveAs("sales.xlsx");

Listを出力する場合は、クラスを用意してループで書き込みます。

C#
using ClosedXML.Excel;

public class SalesRow
{
public string ProductName { get; set; } = "";
public decimal Amount { get; set; }
public DateTime OrderDate { get; set; }
}

var sales = new List<SalesRow>
{
new() { ProductName = "ノートPC", Amount = 120000, OrderDate = new DateTime(2026, 6, 11) },
new() { ProductName = "マウス", Amount = 3000, OrderDate = new DateTime(2026, 6, 12) }
};

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell(1, 1).Value = "商品名";
worksheet.Cell(1, 2).Value = "金額";
worksheet.Cell(1, 3).Value = "受注日";

for (int i = 0; i < sales.Count; i++)
{
var row = i + 2;

worksheet.Cell(row, 1).Value = sales[i].ProductName;
worksheet.Cell(row, 2).Value = sales[i].Amount;
worksheet.Cell(row, 3).Value = sales[i].OrderDate;
}

worksheet.Columns().AdjustToContents();

workbook.SaveAs("sales.xlsx");

5-4. 既存Excelファイルを開いて追記・更新する

既存のExcelファイルを開いて、値を追記・更新する例です。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook("template.xlsx");
var worksheet = workbook.Worksheet("売上");

var lastRow = worksheet.LastRowUsed().RowNumber();
var newRow = lastRow + 1;

worksheet.Cell(newRow, 1).Value = "キーボード";
worksheet.Cell(newRow, 2).Value = 8000;
worksheet.Cell(newRow, 3).Value = DateTime.Today;

workbook.SaveAs("output.xlsx");

テンプレートを上書きしたくない場合は、読み込み元と保存先を分けることが重要です。

C#
using var workbook = new XLWorkbook("template.xlsx");

// 値を書き込む

workbook.SaveAs("report_202606.xlsx");

5-5. 複数シートを作成してデータを書き込む

複数シートを作成する場合は、Worksheets.Addを複数回呼び出します。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();

var salesSheet = workbook.Worksheets.Add("売上");
salesSheet.Cell("A1").Value = "売上データ";

var stockSheet = workbook.Worksheets.Add("在庫");
stockSheet.Cell("A1").Value = "在庫データ";

var summarySheet = workbook.Worksheets.Add("集計");
summarySheet.Cell("A1").Value = "集計結果";

workbook.SaveAs("report.xlsx");

月別、部門別、カテゴリ別などでシートを分けると、ユーザーがExcel上で確認しやすくなります。ただし、シート数が多すぎると扱いにくくなるため、必要以上に分割しないようにしましょう。

5-6. ファイルを保存する処理の書き方

ファイル保存では、保存先ディレクトリの存在確認や同名ファイルの扱いに注意します。

C#
using ClosedXML.Excel;

var outputDir = @"C:\temp\excel";
Directory.CreateDirectory(outputDir);

var fileName = $"sales_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
var outputPath = Path.Combine(outputDir, fileName);

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";

workbook.SaveAs(outputPath);

ファイル名に日時を含めると、同名ファイルの上書きを避けやすくなります。Webアプリの場合は、サーバーに保存せずMemoryStreamでダウンロードさせる実装もよく使われます。

6. C#でExcel出力する実装例

6-1. コンソールアプリでExcelファイルを出力する

コンソールアプリでExcelを出力する最小構成の例です。

C#
using ClosedXML.Excel;

Console.WriteLine("Excel出力を開始します。");

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";

worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

worksheet.Cell("A3").Value = "マウス";
worksheet.Cell("B3").Value = 3000;

worksheet.Columns().AdjustToContents();

var outputPath = Path.Combine(Environment.CurrentDirectory, "sales.xlsx");
workbook.SaveAs(outputPath);

Console.WriteLine($"Excel出力が完了しました: {outputPath}");

バッチ処理や定期実行ジョブでExcelレポートを作る場合、このような構成が基本になります。

6-2. Windowsフォーム・WPFアプリでExcelを出力する

WindowsフォームやWPFでは、ユーザーに保存先を選んでもらってExcelを出力することがよくあります。

WPFの例です。

C#
using ClosedXML.Excel;
using Microsoft.Win32;

var dialog = new SaveFileDialog
{
Filter = "Excelファイル (*.xlsx)|*.xlsx",
FileName = "sales.xlsx"
};

if (dialog.ShowDialog() == true)
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";
worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

worksheet.Columns().AdjustToContents();

workbook.SaveAs(dialog.FileName);
}

デスクトップアプリでは、出力後にExcelファイルを開く処理を追加することもあります。

C#
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = dialog.FileName,
UseShellExecute = true
});

6-3. ASP.NET CoreでExcelファイルをダウンロード出力する

ASP.NET CoreでExcelファイルをダウンロードさせる場合は、MemoryStreamに保存してFileで返します。

C#
using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/reports")]
public class ReportsController : ControllerBase
{
[HttpGet("sales")]
public IActionResult DownloadSalesReport()
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";
worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

worksheet.Columns().AdjustToContents();

using var stream = new MemoryStream();
workbook.SaveAs(stream);

var content = stream.ToArray();
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var fileName = $"sales_{DateTime.Now:yyyyMMddHHmmss}.xlsx";

return File(content, contentType, fileName);
}
}

Webアプリでは、ユーザーごとに同時アクセスが発生します。固定ファイル名でサーバーに一時保存すると競合しやすいため、MemoryStreamで直接返すか、一時ファイル名を一意にする設計が安全です。

6-4. テンプレートExcelを使って帳票を出力する

請求書や見積書など、レイアウトが重要な帳票では、テンプレートExcelを用意して値だけを差し込む方法が便利です。

C#
using ClosedXML.Excel;

var templatePath = "Templates/invoice_template.xlsx";
var outputPath = "invoice_20260611.xlsx";

using var workbook = new XLWorkbook(templatePath);
var worksheet = workbook.Worksheet("請求書");

worksheet.Cell("B3").Value = "株式会社サンプル";
worksheet.Cell("F3").Value = DateTime.Today;
worksheet.Cell("B8").Value = "システム開発費";
worksheet.Cell("E8").Value = 1;
worksheet.Cell("F8").Value = 300000;

workbook.SaveAs(outputPath);

テンプレート方式のメリットは、罫線、ロゴ、印刷範囲、ページ設定などをExcel側で調整できることです。開発者がC#コードで細かくレイアウトを作り込む必要が少なくなります。

6-5. CSVではなくExcel形式で出力するメリット

CSVではなくExcel形式で出力するメリットは、見た目や機能を含めて保存できることです。

Excel形式では、次のようなことができます。

機能Excel形式CSV
複数シート×
罫線・背景色×
列幅調整×
セル結合×
数式×
フィルター×
印刷設定×

単純なデータ連携ならCSVで十分ですが、ユーザーがExcelで開いて確認・印刷・加工する前提なら、xlsx形式で出力する価値があります。

6-6. 出力ファイル名や保存先を指定する方法

ファイル名には、帳票名、対象日、出力日時などを含めると管理しやすくなります。

C#
var reportDate = new DateTime(2026, 6, 11);
var fileName = $"売上レポート_{reportDate:yyyyMMdd}.xlsx";

使用できない文字を除去する処理も入れておくと安全です。

C#
static string SanitizeFileName(string fileName)
{
foreach (var c in Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(c, '_');
}

return fileName;
}

var safeFileName = SanitizeFileName("売上レポート:東京支店.xlsx");

保存先を指定する場合は、Path.Combineを使います。

C#
var outputDir = @"C:\reports";
Directory.CreateDirectory(outputDir);

var outputPath = Path.Combine(outputDir, safeFileName);
workbook.SaveAs(outputPath);

文字列連結でパスを作ると、区切り文字のミスが起こりやすいため、Path.Combineを使うのがおすすめです。

7. Excelらしい見た目に整える方法

7-1. セルの背景色・文字色・罫線を設定する

Excel出力では、ヘッダー行に背景色や罫線を設定すると見やすくなります。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";

var headerRange = worksheet.Range("A1:B1");
headerRange.Style.Font.Bold = true;
headerRange.Style.Fill.BackgroundColor = XLColor.LightGray;
headerRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
headerRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;

worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

var dataRange = worksheet.Range("A1:B2");
dataRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
dataRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;

workbook.SaveAs("styled.xlsx");

装飾を入れすぎると逆に見づらくなるため、ヘッダー、合計行、重要項目などに絞って設定するとよいでしょう。

7-2. 列幅・行の高さを自動調整する

列幅を自動調整するには、AdjustToContents()を使います。

C#
worksheet.Columns().AdjustToContents();

特定の列だけ調整することもできます。

C#
worksheet.Column(1).AdjustToContents();
worksheet.Column(2).Width = 15;

行の高さを設定する例です。

C#
worksheet.Row(1).Height = 24;

Excel出力後にユーザーが列幅を手動調整しなくて済むよう、一覧表では列幅調整を入れておくと親切です。

7-3. 数値・日付・通貨の表示形式を設定する

数値、日付、通貨は表示形式を設定しましょう。

C#
worksheet.Cell("A2").Value = DateTime.Today;
worksheet.Cell("A2").Style.DateFormat.Format = "yyyy/mm/dd";

worksheet.Cell("B2").Value = 120000;
worksheet.Cell("B2").Style.NumberFormat.Format = "#,##0";

worksheet.Cell("C2").Value = 120000;
worksheet.Cell("C2").Style.NumberFormat.Format = "¥#,##0";

列全体に設定することもできます。

C#
worksheet.Column(2).Style.NumberFormat.Format = "#,##0";
worksheet.Column(3).Style.DateFormat.Format = "yyyy/mm/dd";

値を文字列として書き込むと、Excel上で並べ替えや集計がしにくくなる場合があります。金額は数値、日付はDateTimeとして書き込み、表示形式で見た目を整えるのが基本です。

7-4. セル結合や中央揃えを設定する

タイトル行などでは、セル結合と中央揃えを使うことがあります。

C#
worksheet.Range("A1:D1").Merge();
worksheet.Cell("A1").Value = "売上レポート";
worksheet.Cell("A1").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
worksheet.Cell("A1").Style.Font.Bold = true;
worksheet.Cell("A1").Style.Font.FontSize = 16;

縦方向の中央揃えも設定できます。

C#
worksheet.Cell("A1").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;

ただし、データ一覧部分でセル結合を多用すると、フィルターや並べ替えが使いにくくなります。セル結合はタイトルや帳票ヘッダーなど、見た目重視の場所に限定するのがおすすめです。

7-5. フィルターやウィンドウ枠固定を設定する

一覧表では、フィルターとウィンドウ枠固定を設定すると使いやすくなります。

C#
var range = worksheet.Range("A1:C10");
range.SetAutoFilter();

worksheet.SheetView.FreezeRows(1);

1列目も固定したい場合は次のようにします。

C#
worksheet.SheetView.Freeze(1, 1);

ヘッダー行を固定しておくと、行数が多いExcelでも列の意味を確認しながらスクロールできます。

7-6. 数式を設定してExcel上で計算させる

C#からExcelの数式を設定することもできます。

C#
worksheet.Cell("A1").Value = "商品名";
worksheet.Cell("B1").Value = "金額";

worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 120000;

worksheet.Cell("A3").Value = "マウス";
worksheet.Cell("B3").Value = 3000;

worksheet.Cell("A4").Value = "合計";
worksheet.Cell("B4").FormulaA1 = "SUM(B2:B3)";

Excelで開いたときに数式として計算されます。集計行や小計、消費税、合計金額などをExcel側で計算させたい場合に便利です。

8. C#でExcel操作するときによくあるエラーと対処法

8-1. ファイルが開けない・保存できない場合

ファイルが開けない、保存できない場合は、まずパスと権限を確認します。

よくある原因は次のとおりです。

原因対処法
ファイルパスが間違っている絶対パス、相対パス、実行ディレクトリを確認する
保存先フォルダが存在しないDirectory.CreateDirectoryで作成する
書き込み権限がないアプリ実行ユーザーの権限を確認する
ファイルがExcelで開かれているファイルを閉じる、別名保存する
ファイル名に禁止文字があるPath.GetInvalidFileNameChars()で除去する

例外処理を入れる場合は、原因をログに残しましょう。

C#
try
{
workbook.SaveAs(outputPath);
}
catch (IOException ex)
{
Console.WriteLine($"ファイル保存に失敗しました: {ex.Message}");
}

8-2. Excelファイルが破損して開けない場合

Excelファイルが破損して開けない場合は、保存処理が途中で失敗している可能性があります。

主な原因は次のとおりです。

原因対処法
ストリームを正しく閉じていないusingを使って確実に破棄する
拡張子と内容が一致していないxlsxならxlsx形式で保存する
保存中に例外が発生しているログを確認する
HTTPレスポンスに不要な文字が混ざっているWeb出力処理を確認する
テンプレートファイル自体が壊れているテンプレートをExcelで開いて確認する

ASP.NET Coreでダウンロード出力する場合、Excelのバイナリ以外の文字列をレスポンスに混ぜないように注意します。

8-3. 日本語や文字コードで文字化けする場合

xlsx形式では、通常は日本語文字化けが問題になることは多くありません。文字化けが起こりやすいのはCSVです。

ExcelでCSVを開く場合、日本語が文字化けすることがあります。対策として、UTF-8 BOM付きで出力する方法があります。

C#
using System.Text;

var lines = new[]
{
"商品名,金額",
"ノートPC,120000"
};

File.WriteAllLines("sales.csv", lines, new UTF8Encoding(true));

古い環境や特定の業務システムと連携する場合は、Shift_JISが求められることもあります。

C#
var encoding = Encoding.GetEncoding("shift_jis");
File.WriteAllLines("sales.csv", lines, encoding);

CSV出力では、連携先が期待する文字コードを確認することが重要です。

8-4. 日付や数値が意図しない形式になる場合

日付や数値が意図しない形式になる場合は、値の型と表示形式を確認します。

悪い例です。

C#
worksheet.Cell("A2").Value = "2026/06/11";
worksheet.Cell("B2").Value = "120000";

この場合、日付や数値ではなく文字列として扱われることがあります。

よい例です。

C#
worksheet.Cell("A2").Value = new DateTime(2026, 6, 11);
worksheet.Cell("A2").Style.DateFormat.Format = "yyyy/mm/dd";

worksheet.Cell("B2").Value = 120000;
worksheet.Cell("B2").Style.NumberFormat.Format = "#,##0";

Excelで集計や並べ替えを行う可能性があるデータは、文字列ではなく適切な型で出力しましょう。

8-5. ファイル使用中でアクセスできない場合

Excelファイルを開いたままC#から上書き保存しようとすると、ファイル使用中でアクセスできないことがあります。

対処法は次のとおりです。

対処法内容
Excelで開いているファイルを閉じる手動操作の場合は最も簡単
別名で保存する上書き競合を避ける
一時ファイルに保存してから置き換える安全に更新する
ファイル名に日時やGUIDを付けるWebアプリの同時アクセス対策

Webアプリでは、固定名のreport.xlsxに毎回保存すると競合しやすくなります。次のように一意なファイル名を使いましょう。

C#
var fileName = $"report_{DateTime.Now:yyyyMMddHHmmss}_{Guid.NewGuid():N}.xlsx";

8-6. サーバー環境でInteropを使うべきではない理由

サーバー環境でMicrosoft.Office.Interop.Excelを使うべきではない主な理由は、Excelが対話型デスクトップアプリケーションとして設計されているためです。

問題になりやすい点は次のとおりです。

問題内容
プロセスが残るExcel.exeが終了せず残ることがある
同時実行に弱い複数リクエストで競合しやすい
権限問題が起きるサービスアカウントで動作しないことがある
ダイアログで停止する非表示の確認ダイアログで処理が止まる可能性がある
サポート対象外Microsoftが非対話型環境でのOffice自動化を推奨・サポートしていない

Microsoftは、非対話型のクライアントアプリケーションやコンポーネントからOfficeアプリケーションを自動化することを推奨・サポートしていないと説明しています。

サーバー側では、ClosedXML、EPPlus、NPOI、Open XML SDKなど、Excel本体を起動しないライブラリを選びましょう。

9. 実務で使うための設計ポイント

9-1. Excel操作処理を共通クラス化する

Excel出力処理を画面やControllerに直接書くと、コードが肥大化しやすくなります。実務では、Excel操作を専用クラスに分けるのがおすすめです。

C#
using ClosedXML.Excel;

public class SalesExcelExporter
{
public byte[] Export(IEnumerable<SalesRow> sales)
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("売上");

worksheet.Cell(1, 1).Value = "商品名";
worksheet.Cell(1, 2).Value = "金額";
worksheet.Cell(1, 3).Value = "受注日";

var row = 2;
foreach (var item in sales)
{
worksheet.Cell(row, 1).Value = item.ProductName;
worksheet.Cell(row, 2).Value = item.Amount;
worksheet.Cell(row, 3).Value = item.OrderDate;
row++;
}

worksheet.Columns().AdjustToContents();

using var stream = new MemoryStream();
workbook.SaveAs(stream);
return stream.ToArray();
}
}

Controller側は、出力されたバイト配列を返すだけにします。

C#
var bytes = exporter.Export(sales);
return File(bytes, contentType, fileName);

このように分けると、Excel出力ロジックの再利用やテストがしやすくなります。

9-2. 大量データ出力でメモリ不足を避ける

Excel出力では、データ量が増えるとメモリ使用量が大きくなります。特にWebアプリでは、複数ユーザーが同時に大きなExcelファイルを出力すると、サーバー負荷が高くなります。

対策としては、次のような方法があります。

対策内容
出力件数に上限を設ける10万件以上などの無制限出力を避ける
検索条件を必須にする全件出力を防ぐ
CSV出力に切り替える書式が不要なら軽量化できる
シートやファイルを分割する1ファイルに詰め込みすぎない
非同期ジョブ化する重い帳票をリクエスト中に作らない
ストリーミング対応を検討する大量データ向けの方式を選ぶ

Excelは便利ですが、大量データの保管や分析に最適な形式とは限りません。業務要件に応じて、Excel、CSV、DB、BIツールなどを使い分けましょう。

9-3. 入力チェックと例外処理を入れる

Excel読み込みでは、ユーザーが想定外のファイルをアップロードすることがあります。

たとえば、次のようなチェックが必要です。

チェック項目内容
拡張子.xlsxかどうか
シート存在必要なシート名があるか
ヘッダー必須列が存在するか
必須値空白ではないか
日付・数値として読めるか
範囲金額や日付が妥当か

ヘッダーを確認する例です。

C#
var requiredHeaders = new[] { "商品名", "金額", "受注日" };

foreach (var header in requiredHeaders)
{
if (!headerMap.ContainsKey(header))
{
throw new InvalidOperationException($"必須列がありません: {header}");
}
}

Excel取り込み処理では、エラーが発生した行番号や列名をユーザーに返すと、修正しやすくなります。

9-4. テンプレートファイルを安全に管理する

帳票テンプレートを使う場合は、テンプレートファイルの管理も重要です。

注意点は次のとおりです。

注意点内容
上書きしないテンプレートは読み取り専用として扱う
バージョン管理するGitなどで変更履歴を管理する
配置先を固定する実行環境で参照できる場所に置く
ユーザー入力でパスを作らないパストラバーサルを防ぐ
テンプレート変更の影響を確認するセル位置変更でコードが壊れないようにする

テンプレートパスは、設定ファイルから取得すると環境ごとの差し替えがしやすくなります。

C#
var templatePath = Path.Combine(
appEnvironment.ContentRootPath,
"Templates",
"invoice_template.xlsx"
);

テンプレートを変更したら、帳票出力のテストも必ず行いましょう。

9-5. 単体テストしやすいExcel出力処理にする

Excel出力処理は、ファイルを直接保存するよりも、バイト配列やStreamを返す設計にするとテストしやすくなります。

C#
public interface IExcelExporter<T>
{
byte[] Export(IEnumerable<T> data);
}

テストでは、出力されたバイト配列を再度ClosedXMLで開き、セルの値を確認できます。

C#
using ClosedXML.Excel;

var exporter = new SalesExcelExporter();
var bytes = exporter.Export(sales);

using var stream = new MemoryStream(bytes);
using var workbook = new XLWorkbook(stream);
var worksheet = workbook.Worksheet("売上");

var header = worksheet.Cell("A1").GetString();

if (header != "商品名")
{
throw new Exception("ヘッダーが正しくありません");
}

見た目の完全な自動テストは難しいですが、シート名、ヘッダー、件数、合計値、主要セルの値はテストできます。

9-6. Webアプリで同時アクセスに対応する

WebアプリでExcel出力を行う場合は、同時アクセスを前提に設計します。

避けるべき実装は、全ユーザーが同じファイル名に出力する方法です。

C#
// 避けたい例
var outputPath = @"C:\temp\report.xlsx";
workbook.SaveAs(outputPath);

複数ユーザーが同時に実行すると、ファイルロックや上書き競合が発生する可能性があります。

安全な方法は、MemoryStreamで直接返すことです。

C#
using var stream = new MemoryStream();
workbook.SaveAs(stream);

return File(
stream.ToArray(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
$"report_{DateTime.Now:yyyyMMddHHmmss}.xlsx"
);

一時ファイルが必要な場合は、GUIDなどで一意なファイル名を作り、処理後に削除する仕組みを入れましょう。

10. C#のExcel操作に関するよくある質問

10-1. C#でExcelを操作するにはどのライブラリがおすすめか

一般的な業務アプリでC#からExcelを読み書きするなら、まずClosedXMLがおすすめです。

理由は、コードが分かりやすく、Excel本体が不要で、セルの読み書き、スタイル設定、シート操作、テーブル出力などを実装しやすいためです。ClosedXMLはExcel 2007以降の.xlsxや.xlsmを扱う.NETライブラリとして公開されています。

ただし、古いxls形式が必要ならNPOI、高度な機能を商用ライセンス前提で使うならEPPlus、大量データやOpen XMLの細かい制御が必要ならOpen XML SDKも候補になります。

10-2. ExcelがインストールされていないPCでも操作できるか

ClosedXML、EPPlus、NPOI、Open XML SDKを使えば、ExcelがインストールされていないPCやサーバーでもExcelファイルを読み書きできます。

一方、Microsoft.Office.Interop.ExcelはExcel本体を操作する方式のため、実行環境にExcelが必要です。サーバー環境ではInteropではなく、Excel本体に依存しないライブラリを使うのが基本です。

10-3. xls形式のファイルも読み書きできるか

xls形式を扱いたい場合は、NPOIが候補になります。NPOIはOffice 2003/2007形式のファイルを読み書きできるライブラリとして説明されています。

ClosedXMLは主に.xlsxや.xlsmを対象とするライブラリです。古いxlsファイルを扱う必要がある場合は、xlsxへ変換するか、NPOIなどxls対応ライブラリを検討しましょう。

10-4. ExcelファイルをPDFに変換できるか

ExcelファイルをPDFに変換する処理は、ライブラリによって対応状況が異なります。

Microsoft.Office.Interop.Excelを使えば、Excel本体の機能でPDF出力できます。ただし、Excel本体が必要で、サーバー環境では推奨されません。

ClosedXMLはExcelファイルの読み書きには便利ですが、Excelの表示結果を完全にPDF化する用途には向いていません。PDF変換が必要な場合は、Excel本体を使うデスクトップ処理にする、商用ライブラリを使う、帳票を最初からPDF生成ライブラリで作る、といった方法を検討するとよいでしょう。

10-5. 無料で商用利用できるライブラリはあるか

ClosedXMLはMIT licenseとして公開されています。 NPOIもオープンソースライブラリとして広く使われていますが、実際に採用する際は、利用するバージョンのLICENSEファイルやNuGet情報を確認してください。

EPPlusは、バージョン5以降、個人・非商用利用は無料ですが、商用ビジネスで使う場合は商用ライセンスが必要と説明されています。

会社のシステムで使う場合は、「無料で使える」と思い込まず、公式のライセンス情報を確認し、必要に応じて法務・管理部門に確認しましょう。

10-6. ClosedXML・EPPlus・NPOIはどれを選ぶべきか

選び方の目安は次のとおりです。

条件おすすめ
初心者で扱いやすさ重視ClosedXML
一般的なxlsx出力ClosedXML
xls形式も扱いたいNPOI
高機能なExcel操作をしたいEPPlus
商用ライセンスを避けたいClosedXMLやNPOIを確認
大量データを効率よく扱いたいNPOIやOpen XML SDKを検討

多くの業務アプリでは、ClosedXMLで十分対応できます。特殊な要件が出てきた段階で、EPPlus、NPOI、Open XML SDKを比較検討するとよいでしょう。

まとめ

C#でExcel操作を行う方法には、Microsoft.Office.Interop.Excel、ClosedXML、EPPlus、NPOI、Open XML SDK、CSV出力などがあります。

WindowsデスクトップでExcel本体の機能を直接使いたい場合はInteropも選択肢になりますが、Webアプリやサーバー環境では避けるべきです。Microsoftも非対話型環境でのOffice自動化を推奨・サポートしていないため、サーバー側ではExcel本体に依存しないライブラリを使いましょう。

初心者や一般的な業務アプリでC#からExcelを読み書きするなら、ClosedXMLが扱いやすくおすすめです。古いxls形式が必要ならNPOI、高機能なExcel操作が必要でライセンス条件を満たせるならEPPlus、大量データや低レベル制御が必要ならOpen XML SDKを検討しましょう。

Excel操作を実務で安定させるには、ライブラリ選びだけでなく、ファイルロック、文字コード、日付・数値の型、テンプレート管理、例外処理、同時アクセス、メモリ使用量にも注意が必要です。

C#でExcel操作を実装すると、読み込み、書き込み、帳票出力、レポート作成など、多くの業務を自動化できます。まずはClosedXMLで基本的な読み書きから始め、要件に応じて最適な方法を選びましょう。