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操作を行う前に、ファイル形式の違いを理解しておきましょう。
| 形式 | 特徴 | 主な用途 |
|---|---|---|
| xlsx | Excel 2007以降の標準形式。Open XML形式 | 通常のExcel出力、読み書き |
| xls | Excel 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で行います。
Bashdotnet 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向けのスプレッドシートライブラリとして提供されています。
インストールは次のように行います。
Bashdotnet 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形式のファイルを読み書きできるライブラリとして公開されています。
インストールは次のとおりです。
Bashdotnet 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要素に対応する厳密に型指定されたクラスでドキュメント構造やコンテンツを作成できると説明されています。
インストールは次のとおりです。
Bashdotnet 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. 迷ったときのおすすめライブラリ比較表
| ライブラリ | 特徴 | xlsx | xls | Excel本体 | 向いている用途 |
|---|---|---|---|---|---|
| ClosedXML | 簡単で読みやすい | ○ | × | 不要 | 一般的な業務アプリ、帳票出力 |
| EPPlus | 高機能 | ○ | × | 不要 | 高度なExcel出力、商用ライセンス前提の開発 |
| NPOI | xlsにも対応 | ○ | ○ | 不要 | 古いxls形式との連携 |
| Open XML SDK | 低レベル制御 | ○ | × | 不要 | 大量データ、細かいOpen XML制御 |
| Interop | Excel本体を操作 | ○ | ○ | 必要 | デスクトップ環境、印刷、PDF変換、マクロ連携 |
| CSV | 軽量なテキスト | × | × | 不要 | 単純な一覧データ出力 |
迷った場合は、まずClosedXMLを検討するとよいでしょう。古いxlsが必要ならNPOI、商用ライセンスを許容して高機能なExcel操作をしたいならEPPlus、大量データや低レベル制御が必要ならOpen XML SDKが候補になります。
4. C#でExcelファイルを読み込む方法
4-1. Excelファイルを開いてシートを取得する
ここからはClosedXMLを使って、C#でExcelファイルを読み込む方法を解説します。
まずはNuGetでClosedXMLをインストールします。
Bashdotnet 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で基本的な読み書きから始め、要件に応じて最適な方法を選びましょう。

