C#でExcelを操作する方法|読み込み・書き込みからライブラリ比較まで徹底解説

はじめに

C#でExcelを操作したい場面は、業務システムやWebアプリケーション開発で非常に多くあります。たとえば、売上データをExcelに出力する、取引先から受け取ったExcelファイルを読み込む、帳票テンプレートに値を差し込んで請求書を作成する、CSVをExcel形式に変換する、といった処理です。

C#でExcelを扱う方法には、Microsoft Office Interop Excelを使ってExcel本体を操作する方法と、ClosedXML、EPPlus、NPOI、Open XML SDKなどのライブラリを使ってExcelファイルを直接読み書きする方法があります。どの方法を選ぶかによって、開発のしやすさ、対応できるファイル形式、ライセンス、サーバー環境での利用可否が大きく変わります。

この記事では、C#でExcelを操作する基本から、読み込み・書き込み・書式設定・ライブラリ比較・実装例・注意点までをまとめて解説します。

1. C#でExcelを操作する方法の全体像

C#でExcelを操作する方法は、大きく分けると「Excelアプリケーションを自動操作する方法」と「Excelファイルをライブラリで直接操作する方法」の2種類があります。

前者はMicrosoft Office Interop Excelを使う方法で、実際にインストールされたExcelをC#から操作します。Excelの機能をそのまま使える一方で、サーバー環境やWebアプリケーションではトラブルが発生しやすいため注意が必要です。

後者はClosedXMLやEPPlus、NPOI、Open XML SDKなどを使う方法です。Excel本体をインストールしなくても、.xlsxや.xlsなどのファイルを読み書きできます。現在のC#開発では、業務システムやASP.NETアプリケーションでExcel出力を行う場合、このライブラリ方式が選ばれることが多いです。

1-1. C#からExcelを操作する主な方法

C#でExcelを操作する主な方法は次のとおりです。

方法特徴Excel本体主な用途
ClosedXML直感的に.xlsxを読み書きできる不要一般的なExcel読み書き、帳票出力
EPPlus高機能で書式・グラフ・テーブル操作に強い不要業務帳票、集計表、商用システム
NPOI.xlsと.xlsxの両方に対応しやすい不要古いExcel形式を含む業務システム
Open XML SDKOpen XMLを低レベルで操作できる不要細かい制御、大規模処理、ライブラリ開発
Microsoft Office Interop ExcelExcelアプリをC#から自動操作する必要デスクトップアプリ、既存マクロ連携

ClosedXMLはExcel 2007以降の.xlsxや.xlsmファイルの読み込み・編集・書き込みを扱う.NETライブラリとして公開されています。Open XML SDKはOpen XMLパッケージを操作するためのMicrosoft公式SDKで、Office文書の構造を直接扱う用途に向いています。GitHub+1

1-2. Excel操作でできること:読み込み・書き込み・編集・出力

C#でExcelを操作すると、次のような処理を自動化できます。

Excelファイルの読み込みでは、指定したセルの値を取得したり、行・列をループして一覧データを取り込んだりできます。読み込んだデータはDataTableやList<T>に変換して、データベース登録や画面表示に利用できます。

Excelファイルへの書き込みでは、新規ファイルを作成し、セルに文字列・数値・日付を書き込めます。さらに、既存のテンプレートExcelを開いて値を差し込み、請求書、見積書、納品書、勤怠表などの帳票として出力することも可能です。

編集処理では、フォント、背景色、罫線、列幅、表示形式、セル結合、折り返し表示などを設定できます。単にデータを出力するだけでなく、人が見やすいExcelファイルをC#から生成できます。

1-3. Excel操作に必要な開発環境

C#でExcel操作を行うための一般的な開発環境は次のとおりです。

Windows環境で開発する場合は、Visual StudioまたはVisual Studio Code、.NET SDK、NuGetパッケージ管理機能があれば始められます。.NET Framework、.NET 6、.NET 8など、利用するプロジェクトに合わせて対応ライブラリを選びます。

たとえばClosedXMLを使う場合は、NuGetで次のようにインストールできます。

Bash
dotnet add package ClosedXML

EPPlusを使う場合は次のように追加します。

Bash
dotnet add package EPPlus

NPOIを使う場合は次のように追加します。

Bash
dotnet add package NPOI

Open XML SDKを使う場合は、DocumentFormat.OpenXmlパッケージを追加します。

Bash
dotnet add package DocumentFormat.OpenXml

1-4. Excel本体が必要な方法と不要な方法の違い

C#でExcelを操作するときに重要なのが、Excel本体のインストールが必要かどうかです。

Microsoft Office Interop Excelを使う場合は、実際のExcelアプリケーションをCOM経由で操作します。そのため、実行環境にMicrosoft Excelがインストールされている必要があります。Excelの機能を細かく使える一方、プロセスが残る、ファイルロックが発生する、サーバー実行で不安定になるといった問題が起こりやすいです。

一方、ClosedXML、EPPlus、NPOI、Open XML SDKなどはExcelファイルそのものを読み書きするため、Excel本体は不要です。ASP.NETやバッチ処理、Linux環境、クラウド環境などでも使いやすく、業務システムではこちらの方式が適しています。

2. C#でExcelを操作するライブラリの選び方

C#でExcelを操作するライブラリを選ぶときは、単に「有名だから」「サンプルが多いから」だけで決めるのではなく、ファイル形式、ライセンス、実行環境、保守性、パフォーマンスを確認することが重要です。

特に業務システムで利用する場合は、ライセンス違反やサーバー障害につながらないよう、事前に利用条件を確認しておきましょう。

2-1. ライブラリ選定で確認すべきポイント

C#のExcelライブラリを選ぶときは、次のポイントを確認します。

まず、対応しているExcel形式です。.xlsxだけでよいのか、古い.xlsも扱う必要があるのかで選択肢が変わります。.xlsx中心ならClosedXMLやEPPlusが使いやすく、.xlsを扱う必要があるならNPOIが候補になります。

次に、読み込みだけなのか、書き込みや書式設定まで必要なのかを確認します。単純なデータ出力だけであれば多くのライブラリで対応できますが、テンプレート帳票、数式、スタイル、グラフ、ピボット、画像挿入などが必要な場合は、ライブラリごとの対応範囲を比較する必要があります。

さらに、商用利用できるか、サーバーで使えるか、メモリ使用量は許容範囲か、保守されているかも重要です。

2-2. 無料で使えるライブラリと有料ライブラリの違い

C#でExcelを操作できるライブラリには、無料で使いやすいものと、商用利用時にライセンス確認が必要なものがあります。

ClosedXMLはオープンソースで使いやすく、.xlsx中心の一般的なExcel操作に向いています。NPOIもオープンソースで、.xlsと.xlsxの両方を扱いたい場合に便利です。Open XML SDKはMicrosoftが提供するSDKで、Open XML形式を低レベルに操作できます。

一方、EPPlusは高機能ですが、バージョン5以降は非商用利用向けのPolyform Noncommercialライセンスと商用ライセンスのデュアルライセンスになっています。業務システムや商用サービスで使う場合は、公式のライセンス条件を確認する必要があります。EPPlus Software+1

無料か有料かだけでなく、「自社の利用形態で問題なく使えるか」を必ず確認しましょう。

2-3. .xlsx・.xls・CSV対応の違い

Excelファイルには主に.xlsxと.xlsがあります。.xlsxはExcel 2007以降で使われるOpen XML形式で、現在のExcelファイルの標準的な形式です。.xlsはExcel 97-2003形式で、古い業務システムや取引先から受け取るファイルで残っている場合があります。

ClosedXMLは主に.xlsxや.xlsm向けで、.xlsには対応していません。NPOIはOffice 2003/2007形式の読み書きを扱える.NET版Apache POIとして公開されており、.xlsを含む古い形式を扱いたい場合に候補になります。GitHub+1

CSVはExcelファイルではなくテキストファイルですが、C#ではStreamReaderやCsvHelperなどで読み込み、ClosedXMLやEPPlusを使って.xlsxとして出力できます。CSVは書式や数式を持たないため、Excelとしての見た目を整えたい場合は.xlsxへ変換すると便利です。

2-4. サーバー環境やWebアプリで使う場合の注意点

ASP.NETやWindowsサービス、バッチ処理、クラウド環境でExcelファイルを出力する場合は、Excel本体を自動操作するMicrosoft Office Interopではなく、Excel不要のライブラリを使うのが基本です。

サーバー上でInteropを使うと、Excelプロセスが残る、同時実行に弱い、権限設定で失敗する、ダイアログが表示されて処理が止まる、ファイルロックが解除されないといった問題が起こりやすくなります。

WebアプリでExcelを出力する場合は、メモリ上にワークブックを作成し、HTTPレスポンスとしてダウンロードさせる実装が一般的です。このとき、一時ファイルを使う場合は保存先の権限、ファイル名の重複、削除処理にも注意します。

2-5. 業務システムで使いやすいライブラリの選び方

業務システムでC#からExcelを操作するなら、次のように選ぶと失敗しにくいです。

.xlsxの読み書きと基本的な帳票出力が中心であれば、ClosedXMLが扱いやすいです。APIが直感的で、セル、行、列、ワークシート、スタイルを比較的簡単に操作できます。

.xls形式を扱う必要がある場合は、NPOIが候補になります。古いExcelファイルを受け取るシステムや、既存資産として.xlsが残っている環境では便利です。

高度なExcel機能や商用サポートを重視する場合は、EPPlusや有料コンポーネントも検討できます。ただし、EPPlusは商用利用時のライセンス確認が必須です。

Excelファイルの構造を細かく制御したい場合や、大量データを低レベルで扱いたい場合はOpen XML SDKも選択肢になります。ただし、コードはやや複雑になりやすいため、開発効率とのバランスを考える必要があります。

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

C#でExcelファイルを読み込む基本的な流れは、ライブラリをインストールし、Excelファイルを開き、ワークシートを取得し、セルや行列から値を読み取るという手順です。

ここでは、扱いやすいClosedXMLを例に説明します。

3-1. Excelファイルを開いてデータを取得する基本手順

ClosedXMLでExcelファイルを読み込む基本コードは次のとおりです。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook("sample.xlsx");
var worksheet = workbook.Worksheet(1);

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

Console.WriteLine(value);

XLWorkbookでExcelファイルを開き、Worksheet(1)で1枚目のシートを取得します。Cell("A1")のようにセル番地を指定すると、セルの値を読み込めます。

シート名で取得したい場合は、次のように書けます。

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

シート名が固定されている帳票や、取引先から受け取るフォーマットが決まっている場合は、シート名で取得するとコードの意図が分かりやすくなります。

3-2. セルの値を読み込む方法

セルの値は、文字列、数値、日付など用途に応じて取得します。

C#
string name = worksheet.Cell("A2").GetString();
int quantity = worksheet.Cell("B2").GetValue<int>();
decimal price = worksheet.Cell("C2").GetValue<decimal>();
DateTime orderDate = worksheet.Cell("D2").GetValue<DateTime>();

文字列として取得したい場合はGetString()を使うと便利です。数値や日付として扱いたい場合はGetValue<T>()を使います。

ただし、Excel上で空欄になっているセルや、数値として扱いたいセルに文字列が入っている場合は例外が発生することがあります。業務データを読み込む場合は、次のようにチェックを入れると安全です。

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

if (!cell.IsEmpty())
{
int quantity = cell.GetValue<int>();
}

値の型が不安定なExcelを読み込む場合は、一度文字列として取得してからint.TryParsedecimal.TryParseで変換する方法も有効です。

3-3. 行・列をループして一覧データを取得する方法

一覧形式のExcelを読み込む場合は、使用されている行をループします。

C#
using ClosedXML.Excel;

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

foreach (var row in worksheet.RowsUsed().Skip(1))
{
string productName = row.Cell(1).GetString();
int quantity = row.Cell(2).GetValue<int>();
decimal amount = row.Cell(3).GetValue<decimal>();

Console.WriteLine($"{productName} / {quantity} / {amount}");
}

RowsUsed()は値が入っている行を取得します。1行目がヘッダーの場合は、Skip(1)で2行目以降を処理します。

列番号は1始まりです。row.Cell(1)はA列、row.Cell(2)はB列を表します。

3-4. DataTableやListに変換して扱う方法

Excelデータを読み込んだ後は、DataTableやListに変換すると扱いやすくなります。業務アプリケーションでは、読み込んだExcelデータを一覧画面に表示したり、データベースに登録したりすることが多いためです。

たとえば、Excelの売上一覧をListに変換する例は次のとおりです。

C#
public class SalesRow
{
public string ProductName { get; set; } = "";
public int Quantity { get; set; }
public decimal Amount { get; set; }
}

var salesList = new List<SalesRow>();

foreach (var row in worksheet.RowsUsed().Skip(1))
{
var item = new SalesRow
{
ProductName = row.Cell(1).GetString(),
Quantity = row.Cell(2).GetValue<int>(),
Amount = row.Cell(3).GetValue<decimal>()
};

salesList.Add(item);
}

DataTableに変換する場合は次のように書けます。

C#
var table = new DataTable();
table.Columns.Add("商品名", typeof(string));
table.Columns.Add("数量", typeof(int));
table.Columns.Add("金額", typeof(decimal));

foreach (var row in worksheet.RowsUsed().Skip(1))
{
table.Rows.Add(
row.Cell(1).GetString(),
row.Cell(2).GetValue<int>(),
row.Cell(3).GetValue<decimal>()
);
}

画面表示や一時的な表形式データとして使うならDataTable、ドメインモデルとして扱うならList<T>が便利です。

3-5. 読み込み時によくあるエラーと対処法

C#でExcelを読み込むときによくあるエラーには、ファイルが存在しない、シート名が間違っている、セルの型変換に失敗する、ファイルが開かれていてロックされている、といったものがあります。

ファイルが存在しない場合は、読み込み前にFile.Existsで確認します。

C#
if (!File.Exists(filePath))
{
throw new FileNotFoundException("Excelファイルが見つかりません。", filePath);
}

シート名が存在しない可能性がある場合は、ワークシート一覧を確認してから取得します。

C#
var worksheet = workbook.Worksheets
.FirstOrDefault(x => x.Name == "売上");

if (worksheet == null)
{
throw new InvalidOperationException("指定されたシートが存在しません。");
}

型変換エラーを避けるには、文字列として取得してからTryParseで変換します。

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

if (int.TryParse(text, out int quantity))
{
Console.WriteLine(quantity);
}
else
{
Console.WriteLine("数量が数値ではありません。");
}

Excelファイルをユーザーが開いたままにしている場合、保存や上書きでエラーになることがあります。読み込み専用にする、一時ファイルにコピーしてから処理する、ファイルアップロード方式にするなどの対策を検討しましょう。

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

C#でExcelファイルに書き込む処理は、帳票出力やデータエクスポートでよく使われます。新規ファイルを作成する方法と、既存のテンプレートファイルを開いて編集する方法があります。

ここでもClosedXMLを中心に解説します。

4-1. 新規Excelファイルを作成する方法

新しい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("C1").Value = "金額";

workbook.SaveAs("sales.xlsx");

XLWorkbookを新規作成し、Worksheets.Addでシートを追加します。セルに値を設定し、最後にSaveAsで保存します。

4-2. セルに文字列・数値・日付を書き込む方法

セルには文字列、数値、日付などを直接書き込めます。

C#
worksheet.Cell("A2").Value = "ノートPC";
worksheet.Cell("B2").Value = 3;
worksheet.Cell("C2").Value = 450000;
worksheet.Cell("D2").Value = DateTime.Today;

日付を書き込む場合は、表示形式も合わせて設定するとExcel上で見やすくなります。

C#
worksheet.Cell("D2").Style.DateFormat.Format = "yyyy/mm/dd";

通貨や金額は、数値として書き込んだうえで表示形式を設定します。

C#
worksheet.Cell("C2").Style.NumberFormat.Format = "#,##0";

数値を文字列として書き込むと、Excel上で計算や集計がしにくくなるため、数量や金額はできるだけ数値型で書き込みましょう。

4-3. 複数行のデータを一括で書き込む方法

一覧データをExcelに出力する場合は、List<T>をループして書き込みます。

C#
var sales = new List<SalesRow>
{
new SalesRow { ProductName = "ノートPC", Quantity = 3, Amount = 450000 },
new SalesRow { ProductName = "モニター", Quantity = 5, Amount = 125000 },
new SalesRow { ProductName = "キーボード", Quantity = 10, Amount = 80000 }
};

worksheet.Cell(1, 1).Value = "商品名";
worksheet.Cell(1, 2).Value = "数量";
worksheet.Cell(1, 3).Value = "金額";

int rowIndex = 2;

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

worksheet.Columns().AdjustToContents();
workbook.SaveAs("sales.xlsx");

Cell(row, column)を使うと、行番号と列番号でセルを指定できます。大量データを扱う場合は、この形式の方がループ処理に向いています。

4-4. 既存のExcelファイルを編集して保存する方法

既存のExcelファイルを編集する場合は、テンプレートファイルを開いて値を書き込み、別名保存する方法がよく使われます。

C#
using ClosedXML.Excel;

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

worksheet.Cell("B2").Value = "株式会社サンプル";
worksheet.Cell("B3").Value = DateTime.Today;
worksheet.Cell("B4").Value = "INV-20260618";

workbook.SaveAs("invoice.xlsx");

テンプレート方式を使うと、レイアウトや罫線、ロゴ、固定文言などをExcel側で作り込めます。C#側では必要なセルに値を差し込むだけでよいため、帳票作成の保守性が高くなります。

既存ファイルを上書きする場合は、ファイルが開かれていないことを確認しましょう。上書き保存でエラーが発生する場合は、別ファイル名で保存してから置き換える方法もあります。

4-5. 書き込み時の文字化け・型変換エラーの対処法

.xlsxファイルにClosedXMLやEPPlusで書き込む場合、通常は文字コードを強く意識する必要はありません。ただし、CSVを読み込んでExcelに変換する場合は、CSVの文字コードに注意が必要です。

Shift_JISのCSVをUTF-8として読み込むと、日本語が文字化けします。CSVを扱う場合は、入力ファイルの文字コードを確認し、必要に応じてエンコーディングを指定します。

C#
using var reader = new StreamReader("data.csv", Encoding.GetEncoding("shift_jis"));

.NET Coreや.NET 5以降でShift_JISを使う場合は、エンコーディングプロバイダーの登録が必要になることがあります。

C#
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

型変換エラーを避けるには、Excelに書き込む前にデータ型をそろえます。金額はdecimal、数量はint、日付はDateTimeなど、モデル側で型を明確にしておくと安全です。

5. C#でExcelの見た目や書式を設定する方法

Excel出力では、単にデータを書き込むだけでなく、見やすい形式に整えることが重要です。見出しに色を付ける、罫線を引く、列幅を調整する、金額にカンマを付けるなどの処理を行うことで、業務で使いやすいExcelファイルになります。

5-1. セルの背景色・文字色・フォントを変更する方法

ClosedXMLでは、セルのStyleプロパティを使って書式を設定できます。

C#
var header = worksheet.Range("A1:C1");

header.Style.Fill.BackgroundColor = XLColor.LightGray;
header.Style.Font.Bold = true;
header.Style.Font.FontColor = XLColor.Black;
header.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;

特定のセルだけに書式を設定する場合は次のように書きます。

C#
worksheet.Cell("A1").Style.Font.Bold = true;
worksheet.Cell("A1").Style.Font.FontSize = 14;

見出し行には太字、背景色、中央寄せを設定すると、一覧表として見やすくなります。

5-2. 罫線や列幅を設定する方法

罫線を設定するには、範囲を指定してBorderを設定します。

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

tableRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
tableRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin;

列幅を自動調整する場合は、次のように書けます。

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

特定の列幅を指定する場合は、次のように設定します。

C#
worksheet.Column(1).Width = 25;
worksheet.Column(2).Width = 10;
worksheet.Column(3).Width = 15;

帳票では、項目名が長い列や備考欄の列幅を広めに設定すると使いやすくなります。

5-3. 数値・日付・通貨などの表示形式を設定する方法

Excelでは、値そのものと表示形式を分けて考えることが重要です。たとえば金額は数値として保持し、表示上はカンマ区切りや通貨記号を付けます。

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

日付の表示形式は次のように設定します。

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

通貨表示にする場合は、次のように設定できます。

C#
worksheet.Cell("E2").Value = 9800;
worksheet.Cell("E2").Style.NumberFormat.Format = "¥#,##0";

表示形式を設定しておくと、Excel上で見やすいだけでなく、数式や集計にも利用しやすくなります。

5-4. セル結合や折り返し表示を設定する方法

帳票のタイトル部分では、複数セルを結合して中央に表示することがあります。

C#
worksheet.Range("A1:E1").Merge();
worksheet.Cell("A1").Value = "売上一覧表";
worksheet.Cell("A1").Style.Font.Bold = true;
worksheet.Cell("A1").Style.Font.FontSize = 16;
worksheet.Cell("A1").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;

長い文章をセル内で折り返す場合は、次のように設定します。

C#
worksheet.Cell("A5").Value = "備考欄に長い文章を入力します。";
worksheet.Cell("A5").Style.Alignment.WrapText = true;

セル結合は見た目を整えるのに便利ですが、データの並べ替えやフィルターには不向きな場合があります。一覧データではセル結合を避け、帳票のタイトルやヘッダー部分に限定して使うとよいでしょう。

5-5. テンプレートExcelを使って帳票を作成する方法

実務では、C#だけでゼロから帳票レイアウトを作るよりも、Excelで作成したテンプレートファイルに値を差し込む方法がよく使われます。

テンプレート方式のメリットは、レイアウト変更をExcel側で行えることです。たとえば、請求書のロゴ位置、会社情報、罫線、印刷範囲などはExcelテンプレートに設定しておき、C#では顧客名、請求日、明細、合計金額だけを書き込みます。

C#
using var workbook = new XLWorkbook("invoice_template.xlsx");
var worksheet = workbook.Worksheet("請求書");

worksheet.Cell("B3").Value = "株式会社テスト";
worksheet.Cell("E3").Value = DateTime.Today;
worksheet.Cell("B6").Value = "システム開発費";
worksheet.Cell("D6").Value = 1;
worksheet.Cell("E6").Value = 500000;

worksheet.Cell("E10").FormulaA1 = "SUM(E6:E9)";

workbook.SaveAs("invoice_output.xlsx");

帳票レイアウトの変更が多い業務では、テンプレート方式にしておくと、プログラム修正を最小限にできます。

6. C#でExcel操作に使える主要ライブラリ比較

C#でExcelを操作するライブラリには複数の選択肢があります。それぞれ得意分野が異なるため、プロジェクトの要件に合わせて選ぶことが重要です。

6-1. ClosedXMLの特徴と使い方

ClosedXMLは、C#で.xlsxファイルを直感的に操作したい場合に使いやすいライブラリです。セル、行、列、シート、スタイルを分かりやすいAPIで扱えるため、Excel操作に慣れていない開発者でも導入しやすいです。

ClosedXMLの主な特徴は次のとおりです。

項目内容
対応形式主に.xlsx、.xlsm
Excel本体不要
使いやすさ高い
書式設定対応
.xls対応非対応
向いている用途帳票出力、一覧出力、Excel読み込み

基本的な使い方は次のとおりです。

C#
using ClosedXML.Excel;

using var workbook = new XLWorkbook();
var ws = workbook.Worksheets.Add("Sheet1");

ws.Cell("A1").Value = "Hello Excel";
ws.Cell("A1").Style.Font.Bold = true;

workbook.SaveAs("hello.xlsx");

.xlsx中心の業務システムであれば、まず候補に入れたいライブラリです。

6-2. EPPlusの特徴と使い方

EPPlusは、Excelファイルの作成、読み込み、書式設定、テーブル、数式などに対応した高機能な.NET向けライブラリです。APIも比較的扱いやすく、業務帳票やExcel出力で広く使われています。

ただし、EPPlusはバージョン5以降、非商用利用と商用利用でライセンス条件が異なります。商用プロジェクトで利用する場合は、公式のライセンス条件を確認し、必要に応じて商用ライセンスを購入する必要があります。GitHub+1

EPPlusの基本的なコード例は次のとおりです。

C#
using OfficeOpenXml;

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

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

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

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

ライセンス設定方法はバージョンによって異なる場合があるため、実装時は利用中のEPPlusバージョンの公式ドキュメントを確認してください。

6-3. NPOIの特徴と使い方

NPOIは、Apache POIの.NET版として開発されているライブラリです。.xlsと.xlsxの両方を扱いやすい点が特徴です。古いExcel 97-2003形式の.xlsファイルを扱う必要がある場合に有力な候補になります。

NPOIの主な特徴は次のとおりです。

項目内容
対応形式.xls、.xlsxなど
Excel本体不要
使いやすさ中程度
書式設定対応
向いている用途古いExcel形式を含む読み書き

NPOIでは、.xlsの場合はHSSFWorkbook、.xlsxの場合はXSSFWorkbookを使います。

C#
using NPOI.XSSF.UserModel;

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

var row = sheet.CreateRow(0);
row.CreateCell(0).SetCellValue("Hello NPOI");

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

.xlsを扱う場合は次のようにHSSFWorkbookを使います。

C#
using NPOI.HSSF.UserModel;

var workbook = new HSSFWorkbook();
var sheet = workbook.CreateSheet("Sheet1");

var row = sheet.CreateRow(0);
row.CreateCell(0).SetCellValue("Hello XLS");

using var file = new FileStream("sample.xls", FileMode.Create, FileAccess.Write);
workbook.Write(file);

取引先や既存システムの都合で.xls形式が残っている場合は、NPOIを検討するとよいでしょう。

6-4. Open XML SDKの特徴と使い方

Open XML SDKは、Microsoft OfficeのOpen XML形式を操作するためのSDKです。Excelだけでなく、WordやPowerPointのファイルも扱えます。Open XML SDKは、Open XMLパッケージやスキーマ要素を操作するためのAPIを提供しており、低レベルで細かく制御したい場合に向いています。Microsoft Learn+1

一方で、ClosedXMLやEPPlusのような高レベルAPIではないため、単純なExcel出力でもコード量が多くなりやすいです。

Open XML SDKが向いているのは、次のようなケースです。

用途説明
大量データの出力メモリ効率を意識した実装がしやすい
ファイル構造の細かい制御Open XMLの構造を直接扱える
独自ライブラリ開発高レベルAPIの裏側を制御できる
Microsoft標準技術を使いたいMicrosoft公式SDKとして利用できる

通常の業務帳票や一覧出力ではClosedXMLの方が簡単ですが、特殊な要件ではOpen XML SDKが有効です。

6-5. Microsoft Office Interop Excelの特徴と注意点

Microsoft Office Interop Excelは、C#からExcelアプリケーションを自動操作する方法です。実際のExcelを起動してブックを開き、セルを操作し、保存するため、Excelの機能に近い操作ができます。

ただし、Interopは実行環境にExcelがインストールされている必要があります。また、COMオブジェクトの解放漏れによりExcelプロセスが残る、同時実行に弱い、サーバー環境で不安定になるといった問題があります。

デスクトップアプリで、利用者のPCにExcelがインストールされている前提なら選択肢になります。しかし、ASP.NETやWindowsサービス、クラウド環境でのExcel出力には基本的に向いていません。

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

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

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

worksheet.Cells[1, 1] = "Hello Interop";

workbook.SaveAs(@"C:\temp\interop_sample.xlsx");
workbook.Close();
app.Quit();

実務で使う場合は、COMオブジェクトの解放処理を慎重に実装する必要があります。

6-6. 各ライブラリの機能・料金・用途別比較表

C#でExcelを操作する主要ライブラリを比較すると、次のようになります。

ライブラリExcel本体.xlsx.xls書式設定商用利用向いている用途
ClosedXML不要×要ライセンス確認一般的な読み書き、帳票出力
EPPlus不要×商用利用は要確認高機能なExcel出力、業務帳票
NPOI不要要ライセンス確認.xls/.xlsx混在環境
Open XML SDK不要×要ライセンス確認低レベル制御、大量データ
Interop Excel必要Officeライセンス依存デスクトップでのExcel自動操作

「とにかく簡単に.xlsxを読み書きしたい」ならClosedXML、「.xlsも必要」ならNPOI、「高機能なExcel生成をしたい」ならEPPlus、「低レベルに制御したい」ならOpen XML SDK、「Excelアプリそのものを操作したい」ならInteropが候補になります。

7. C#でExcelを操作する実装例

ここからは、C#でExcelを操作する実装例を紹介します。実際の業務システムでよく使う読み込み、書き込み、Excel作成、.xls対応、CSV変換を取り上げます。

7-1. ClosedXMLでExcelを読み込むサンプルコード

次のコードは、ClosedXMLを使ってExcelファイルを読み込み、一覧データをコンソールに表示する例です。

C#
using ClosedXML.Excel;

var filePath = "products.xlsx";

using var workbook = new XLWorkbook(filePath);
var worksheet = workbook.Worksheet("商品一覧");

foreach (var row in worksheet.RowsUsed().Skip(1))
{
var productCode = row.Cell(1).GetString();
var productName = row.Cell(2).GetString();
var price = row.Cell(3).GetValue<decimal>();

Console.WriteLine($"{productCode}: {productName} - {price:#,##0}円");
}

Excelの1行目をヘッダー、2行目以降をデータとして扱っています。商品マスタや売上一覧など、表形式のExcelを読み込むときに使いやすいパターンです。

7-2. ClosedXMLでExcelに書き込むサンプルコード

次のコードは、ListのデータをExcelファイルに出力する例です。

C#
using ClosedXML.Excel;

var products = new[]
{
new { Code = "P001", Name = "ノートPC", Price = 150000 },
new { Code = "P002", Name = "モニター", Price = 30000 },
new { Code = "P003", Name = "キーボード", Price = 8000 }
};

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 = "価格";

int row = 2;

foreach (var product in products)
{
worksheet.Cell(row, 1).Value = product.Code;
worksheet.Cell(row, 2).Value = product.Name;
worksheet.Cell(row, 3).Value = product.Price;
row++;
}

var header = worksheet.Range("A1:C1");
header.Style.Font.Bold = true;
header.Style.Fill.BackgroundColor = XLColor.LightGray;

worksheet.Column(3).Style.NumberFormat.Format = "#,##0";
worksheet.Columns().AdjustToContents();

workbook.SaveAs("products_output.xlsx");

ヘッダーの背景色、太字、価格の表示形式、列幅の自動調整まで行っています。業務で使うExcel出力の基本形として応用できます。

7-3. EPPlusでExcelファイルを作成するサンプルコード

EPPlusでExcelファイルを作成する例は次のとおりです。

C#
using OfficeOpenXml;
using OfficeOpenXml.Style;

// 利用形態に応じて、EPPlusのライセンス設定を行ってください。
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[1, 3].Value = "金額";

worksheet.Cells[2, 1].Value = DateTime.Today;
worksheet.Cells[2, 2].Value = "ノートPC";
worksheet.Cells[2, 3].Value = 150000;

worksheet.Cells[1, 1, 1, 3].Style.Font.Bold = true;
worksheet.Cells[2, 1].Style.Numberformat.Format = "yyyy/mm/dd";
worksheet.Cells[2, 3].Style.Numberformat.Format = "#,##0";

worksheet.Cells.AutoFitColumns();

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

EPPlusは高機能ですが、商用利用ではライセンス確認が必要です。企業システムで導入する場合は、開発前に利用条件を確認しておきましょう。

7-4. NPOIで.xls/.xlsxを扱うサンプルコード

NPOIでは、.xlsxを扱う場合と.xlsを扱う場合で使用するクラスが異なります。

.xlsxファイルを作成する例は次のとおりです。

C#
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");

IRow header = sheet.CreateRow(0);
header.CreateCell(0).SetCellValue("商品名");
header.CreateCell(1).SetCellValue("数量");

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

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

.xlsファイルを作成する場合は、HSSFWorkbookを使います。

C#
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;

IWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");

IRow row = sheet.CreateRow(0);
row.CreateCell(0).SetCellValue("古いExcel形式");

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

古い業務システムでは.xls指定のケースもあります。そのような場合にNPOIは有力な選択肢です。

7-5. CSVを読み込んでExcelに出力するサンプルコード

CSVを読み込んでExcelに変換する場合は、CSVの各行を読み取り、Excelのセルに書き込みます。ここでは簡単なカンマ区切りCSVを想定します。

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

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

var csvPath = "data.csv";
var excelPath = "data.xlsx";

using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("CSVデータ");

using var reader = new StreamReader(csvPath, Encoding.GetEncoding("shift_jis"));

int rowIndex = 1;

while (!reader.EndOfStream)
{
var line = reader.ReadLine();

if (line == null)
{
continue;
}

var values = line.Split(',');

for (int colIndex = 0; colIndex < values.Length; colIndex++)
{
worksheet.Cell(rowIndex, colIndex + 1).Value = values[colIndex];
}

rowIndex++;
}

worksheet.Columns().AdjustToContents();
workbook.SaveAs(excelPath);

ただし、実際のCSVでは、カンマを含む項目、ダブルクォーテーション、改行を含むデータなどがあります。業務用途では、単純にSplit(',')するのではなく、CsvHelperなどのCSVパーサーを使う方が安全です。

8. C#でExcel操作を行うときの注意点

C#でExcel操作を実装するときは、正常系のコードだけでなく、実行環境、パフォーマンス、ファイルロック、ライセンス、例外処理にも注意が必要です。

特に業務システムでは、少量データでは問題なく動いても、大量データや同時アクセスで問題が発生することがあります。

8-1. Microsoft Office Interopをサーバーで使うリスク

Microsoft Office Interop Excelは、Excelアプリケーションを自動操作する仕組みです。そのため、ASP.NETやWindowsサービスのようなサーバーサイド処理には向いていません。

サーバーでInteropを使うと、次のような問題が起こる可能性があります。

問題内容
Excelプロセスが残る例外発生時にEXCEL.EXEが終了しない
同時実行に弱い複数ユーザーの処理が競合しやすい
権限問題サービスアカウントでExcel起動に失敗する
ダイアログ問題警告ダイアログで処理が止まる
ファイルロック保存・削除・上書きが失敗する

Webアプリやサーバー処理では、ClosedXML、EPPlus、NPOI、Open XML SDKなど、Excel本体不要のライブラリを使うのが安全です。

8-2. 大容量Excelファイルを扱う場合のパフォーマンス対策

大量データをExcelに出力する場合は、メモリ使用量と処理時間に注意が必要です。数千行程度であれば問題なくても、数十万行になると処理が重くなることがあります。

パフォーマンス対策としては、次のような方法があります。

対策内容
不要な書式を減らす全セルに個別スタイルを設定しない
セル単位の処理を減らす範囲指定や一括処理を活用する
データ件数を分割するシート分割やファイル分割を検討する
CSV出力も検討する書式不要ならCSVの方が軽い
Open XML SDKを検討する大量データ向けに低レベル制御できる

大量データを出力するときは、すべてのセルに罫線や背景色を設定すると処理が重くなりやすいです。必要最小限の書式に抑えることが重要です。

8-3. ファイルロックや保存エラーの対処法

Excel操作でよくあるトラブルが、ファイルロックや保存エラーです。ユーザーがExcelファイルを開いたままにしていると、上書き保存できないことがあります。

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

まず、読み込み専用で処理できる場合は、元ファイルを直接編集せず、一時ファイルにコピーしてから処理します。

C#
var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".xlsx");
File.Copy(originalPath, tempPath, overwrite: true);

保存時には、いきなり本番ファイルを上書きせず、一時ファイルとして保存してから置き換えると安全です。

C#
var outputPath = "output.xlsx";
var tempOutputPath = "output_temp.xlsx";

workbook.SaveAs(tempOutputPath);

if (File.Exists(outputPath))
{
File.Delete(outputPath);
}

File.Move(tempOutputPath, outputPath);

Webアプリでは、サーバー上の共有フォルダに保存するよりも、メモリ上で生成してユーザーにダウンロードさせる方が扱いやすい場合があります。

8-4. ライセンス違反を避けるための確認ポイント

Excelライブラリを業務システムで使う場合は、ライセンス確認が欠かせません。

確認すべきポイントは次のとおりです。

確認項目内容
商用利用可否会社の業務システムで使えるか
SaaS利用可否外部ユーザー向けサービスで使えるか
配布可否アプリに組み込んで配布できるか
バージョン差旧バージョンと新バージョンでライセンスが違わないか
サポート有償サポートが必要か

特にEPPlusのように、バージョンによってライセンス条件が大きく変わったライブラリでは注意が必要です。個人開発、社内利用、商用サービス、受託開発では条件が異なる場合があるため、公式情報を確認してから導入しましょう。

8-5. 例外処理とusingによるリソース解放

Excelファイルを扱うときは、ファイルストリームやワークブックを適切に解放することが大切です。C#ではusingを使うことで、処理終了時にリソースを解放できます。

C#
try
{
using var workbook = new XLWorkbook("input.xlsx");
var worksheet = workbook.Worksheet(1);

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

Console.WriteLine(value);
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"ファイルが見つかりません: {ex.Message}");
}
catch (IOException ex)
{
Console.WriteLine($"ファイル入出力エラー: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"予期しないエラー: {ex.Message}");
}

保存処理でも例外が発生する可能性があります。ファイルが開かれている、保存先フォルダに権限がない、ディスク容量が不足している、といったケースを想定しておきましょう。

9. C#のExcel操作でよくある質問

C#でExcelを操作する際によくある疑問をまとめます。

9-1. C#でExcelを操作するにはExcelのインストールが必要?

Microsoft Office Interop Excelを使う場合は、実行環境にExcelのインストールが必要です。

一方、ClosedXML、EPPlus、NPOI、Open XML SDKなどのライブラリを使う場合は、Excel本体をインストールしなくてもExcelファイルを読み書きできます。ASP.NETやバッチ処理、サーバー環境でExcel出力を行う場合は、Excel不要のライブラリを使うのが一般的です。

9-2. 無料で使えるおすすめライブラリはどれ?

.xlsxを中心に扱うならClosedXMLが使いやすいです。APIが直感的で、読み込み、書き込み、書式設定、テンプレート編集などの一般的なExcel操作に対応できます。

.xls形式も扱う必要がある場合はNPOIが候補になります。古いExcel形式を含む業務システムでは便利です。

ただし、無料で使えるかどうかは利用目的やライセンス条件によって変わります。商用利用、SaaS、受託開発、再配布などのケースでは、必ず各ライブラリの公式ライセンスを確認してください。

9-3. .xls形式のExcelファイルも扱える?

.xls形式を扱いたい場合は、NPOIやMicrosoft Office Interop Excelが候補になります。

ClosedXMLやEPPlusは主に.xlsx形式向けのライブラリです。そのため、古い.xlsファイルを読み書きしたい場合はNPOIを検討するとよいでしょう。

ただし、可能であれば.xlsを.xlsxへ移行することも検討してください。.xlsxの方が現在のExcel環境では扱いやすく、ライブラリの選択肢も広がります。

9-4. ASP.NETやWebアプリでもExcel出力できる?

ASP.NETやWebアプリでもExcel出力は可能です。ClosedXML、EPPlus、NPOI、Open XML SDKなどを使えば、サーバー上でExcelファイルを生成し、ブラウザからダウンロードさせることができます。

ClosedXMLでASP.NET CoreからExcelを返す例は次のとおりです。

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

public IActionResult DownloadExcel()
{
using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sheet1");

worksheet.Cell("A1").Value = "Hello Excel";

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

var content = stream.ToArray();

return File(
content,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"sample.xlsx"
);
}

Webアプリでは、サーバーのディスクに保存せず、MemoryStreamで生成してそのまま返す方法がよく使われます。

9-5. 大量データを高速にExcel出力するには?

大量データを高速にExcel出力するには、書式設定を最小限にし、セル単位の細かい処理を減らすことが重要です。

特に、数万行以上のデータを出力する場合は、すべてのセルに個別のスタイルを設定すると処理が遅くなりやすいです。ヘッダー行だけに書式を設定し、データ行は表示形式を列単位で設定するなどの工夫をしましょう。

また、Excel形式にこだわらない場合はCSV出力も検討できます。CSVは書式を持たないため、Excelよりも高速かつ軽量に出力できます。

どうしても大量の.xlsxを生成する必要がある場合は、Open XML SDKを使ったストリーミング処理や、専用のExcelコンポーネントの利用も検討するとよいでしょう。

まとめ

C#でExcelを操作する方法には、Microsoft Office Interop Excelを使う方法と、ClosedXML、EPPlus、NPOI、Open XML SDKなどのライブラリを使う方法があります。

現在の業務システムやWebアプリケーションでは、Excel本体を必要としないライブラリ方式が使いやすいです。.xlsxの読み書きや帳票出力が中心ならClosedXML、.xls形式も扱うならNPOI、高機能なExcel生成を求めるならEPPlus、低レベルで細かく制御したいならOpen XML SDKが候補になります。

C#でExcelを読み込む場合は、セルの値、行・列のループ、DataTableやListへの変換を押さえておくと実務で応用しやすくなります。書き込みでは、新規作成、既存ファイル編集、テンプレート帳票、書式設定を組み合わせることで、見やすく使いやすいExcelファイルを自動生成できます。

一方で、サーバー環境でのInterop利用、ライセンス違反、大容量ファイルのパフォーマンス、ファイルロック、例外処理には注意が必要です。特に商用システムでは、ライブラリの利用条件を事前に確認し、運用環境に合った方式を選びましょう。

C#とExcel操作を組み合わせることで、手作業の集計や帳票作成を大幅に自動化できます。まずはClosedXMLなど扱いやすいライブラリから試し、要件に応じてEPPlus、NPOI、Open XML SDKを使い分けるのがおすすめです。