業務システムの開発において、エクセル(Excel)ファイルのデータを読み込んでデータベースに登録したり、計算処理を行ったりする機能は欠かせません。
かつて主流だったMicrosoft Office Interop Excelによる手法(COM参照)は、サーバーサイドやバックグラウンドでの自動処理用途では推奨されていません。
この記事では、C#におけるエクセル読み込みの最新スタンダードであるClosedXMLとExcelDataReaderを中心に、特定のセルを指定した取得方法や、データを一括でDataTable(データテーブル)へ変換する手順など、実務で即戦力となるテクニックを詳しく解説します。
![]() 執筆者:マヒロ |
|
- OS:Windows 11 / macOS Sequoia
- IDE:Visual Studio / VS Code / IntelliJ IDEA
- その他:Chrome DevTools / 各言語最新安定版
※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。
C#でエクセルを読み込むための主なライブラリと比較
C#でエクセル操作を行うライブラリはいくつか存在しますが、用途によって最適な選択肢が異なります。
それぞれの特徴を理解して使い分けることが、開発効率とパフォーマンス向上の鍵となります。
ClosedXML(標準的な読み書きに最適)
ClosedXMLは、Open XML SDKをベースにした非常に人気のあるライブラリです。
オブジェクト指向で直感的なコードを書くことができ、セルのスタイル変更や書き込みも得意としています。
Excelがインストールされていない環境でも動作し、一般的な業務アプリでの .xlsx 形式操作において、有力な選択肢となります。
ただし、数十万行を超えるような極端に大規模なファイルでは、メモリ消費が激しくなる傾向がある点には注意が必要です。
ExcelDataReader(読み込み専用で高速・軽量)
読み込み速度を最優先し、かつ古い .xls 形式にも対応させたい場合にはExcelDataReaderが適しています。
ストリーム形式でデータを読み込むため、後述する逐次処理を組み合わせることで、巨大なファイルでもメモリ負荷を抑えた処理が可能です。
Microsoft Office Interop Excel(環境を選ぶレガシー技術)
COM参照を利用する古い手法です。Microsoft公式もサーバー用途での使用を非推奨としていますが、デスクトップアプリ(WPF/WinForms)で、Excelの高度なグラフ作成やマクロ実行、複雑な既存テンプレートの忠実な再現が必要な場面では、現在も現役で利用されることがあります。
その他の選択肢(EPPlusなど)
他にも、商用利用でのライセンスに注意が必要ですが、非常に高速で多機能なEPPlusというライブラリも有名です。
プロジェクトの予算や要件に応じて比較検討することをおすすめします。
【推奨】ClosedXMLを使ったエクセルファイルの読み込み手順
まずは、最も汎用性が高いClosedXMLを使用した実装方法を紹介します。
NuGetパッケージマネージャーから ClosedXML をインストールするだけで準備は完了です。
ワークシートの全データを読み込むサンプルコード
using ClosedXML.Excel;
using System;
using System.Linq;
class Program
{
static void Main()
{
string filePath = @"C:\temp\SampleData.xlsx";
// 1. ブック(Excelファイル)を開く
using (var workbook = new XLWorkbook(filePath))
{
// 2. 最初のシートを取得
var worksheet = workbook.Worksheet(1);
// 3. データが入っている範囲を特定し、行ごとにループ
// FirstRowUsed() は最初のデータ行、RowsUsed() はデータがある全行を取得
foreach (var row in worksheet.RowsUsed())
{
// セルの値を文字列として取得
string id = row.Cell(1).GetString(); // 1列目
string name = row.Cell(2).GetString(); // 2列目
string score = row.Cell(3).GetString(); // 3列目
Console.WriteLine($"ID: {id}, 名前: {name}, 得点: {score}");
}
}
}
}
このソースコードの仕組みを詳しく解説します。
まず、XLWorkbook クラスを使用してエクセルファイルをメモリ上に展開します。
using ステートメントを使うことで、処理が終わった瞬間にファイルハンドルを確実に解放し、他のプログラムがファイルを開けなくなるトラブルを防いでいます。
次に、workbook.Worksheet(1) で1番目のシートを選択していますが、Worksheet("Sheet1") のようにシート名で直接指定することも可能です。
RowsUsed() メソッドは、空白以外のデータが含まれている行だけを効率的に抽出してくれる便利な機能です。
各行(row)の中では、Cell(列番号) を指定して個別のデータにアクセスします。
このように、エクセルの構造をそのままオブジェクトとして扱えるのがClosedXMLのメリットと言えます。
ExcelDataReaderで大規模なエクセルデータを読み込む方法
数万行を超えるファイルを一括で処理したい場合、ExcelDataReaderを活用してデータを一括でDataTableに読み込むのが効率的です。
DataTableへ一括変換して読み込むサンプルコード
using ExcelDataReader;
using System;
using System.Data;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string filePath = "BigData.xlsx";
// エンコーディングの登録(ExcelDataReaderで日本語や.xlsを扱う場合に推奨)
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
// 拡張子に基づいて適切なリーダーを作成
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
// DataSet(全てのシート)として一括取得
// AsDataSetは手軽ですが、極端に巨大なデータの場合は
// reader.Read()を使って一行ずつ処理することで、よりメモリを節約できます
var result = reader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
{
// 1行目をカラム名(ヘッダー)として扱う設定
UseHeaderRow = true
}
});
// 最初のシートをDataTableとして取得
DataTable table = result.Tables[0];
foreach (DataRow row in table.Rows)
{
// カラム名でアクセスできるので可読性が高い
Console.WriteLine($"ユーザー: {row["UserName"]}, 更新日: {row["UpdateDate"]}");
}
}
}
}
}
ExcelDataReaderはファイルを逐次読み込むストリーム形式を採用しているため、大容量ファイルに強い性質があります。
サンプルコードの AsDataSet メソッドは非常に手軽ですが、実体としては全てのデータを一度メモリ上の DataTable に展開するため、物理メモリを超えるような巨大なデータ(数十万行〜)を扱う際は、reader.Read() ループを用いた一行ずつの逐次処理に書き換えることで、さらにパフォーマンスを最適化できます。
特定のセルを指定してピンポイントでデータを取得する
表全体ではなく、特定のセル(例えば「B5」や「C10」など)に入力された値だけを取得したいケースもあります。
ClosedXMLを使えば、エクセルで使い慣れたアドレス形式で直接アクセスすることが可能です。
アドレス形式でセルを取得するコード
using ClosedXML.Excel;
using System;
class Program
{
static void Main()
{
using (var workbook = new XLWorkbook("Invoice.xlsx"))
{
var sheet = workbook.Worksheet(1);
// B5セルの値を文字列として取得
var customerName = sheet.Cell("B5").GetValue<string>();
// 数値として取得(計算が必要な場合)
var totalAmount = sheet.Cell("F20").GetValue<int>();
Console.WriteLine($"宛名: {customerName}");
Console.WriteLine($"合計: {totalAmount}円");
}
}
}
sheet.Cell("B5") のように、文字列でエクセルのセル番号を直接指定できるのが非常に強力です。
GetValue<T>() メソッドを使えば、取得と同時に型変換も行ってくれるため、プログラム内での数値計算もスムーズに進められます。
特定のフォーマットが決まっている注文書や請求書から、決まった場所にあるデータを抜き出すような自動化ツールにおいて、この直感的な指定方法は開発ミスを減らす助けとなります。
エクセル読み込みがうまくいかない時のチェックポイント
コードを正しく書いたつもりでも、実行環境やファイルの状態によって読み込みに失敗することがあります。
C#でエクセルがうまく読み込めないという事態を防ぐために、以下の点を確認してください。
1. ファイルが他のソフトで開かれていないか
エクセルファイルをExcel本体や他のアプリで開いたまま実行すると、ファイルが「ロック」されているため、読み込み時にエラー(IOException)が発生します。
実務で不特定多数のユーザーが利用するシステムであれば、読み込み専用モード(FileShare.ReadWrite)でストリームを開くなどの工夫が必要です。
2. 文字コード(CodePages)の設定漏れ
.NET Core環境以降で ExcelDataReader や古い .xls 形式を扱う場合、日本語(Shift-JIS等)を正しく認識できずにエラーになることがあります。
解決には、NuGetで System.Text.Encoding.CodePages を導入し、プログラムの起動時に Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); を実行してください。
これは .xlsx のみ扱う場合でも、安全のために記述しておくのが実務上の定石です。
3. 空白行や非表示行の扱い
ユーザーが作成したエクセルには、見た目では分からない「書式だけ設定された空白行」が含まれていることがあります。
RowsUsed() を使うことで実質的なデータ行に絞り込むことができますが、より堅牢にするには if (string.IsNullOrWhiteSpace(cell.Value.ToString())) といった値のチェックをループ内に入れて、不要な空データを弾く処理を追加するのが安全です。
C#のスキルを活かして年収を上げる方法
以上、C#でエクセルファイルを読み込む方法について解説してきました。
業務システム開発やアプリ開発、ゲーム開発において需要の高いC#を扱えるエンジニアは、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。
なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。
転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。
| 年収アップにこだわりたい方 (平均アップ額138万円の実績) | テックゴー |
| 未経験・経験者問わず幅広く探したい方 | ユニゾンキャリア |
| 業界に精通した担当者に相談したい方 | キッカケエージェント |
| ゲーム業界への転職を志望する方 | ファミキャリ |
| エンジニア未経験からキャリアを築く方 | イーチキャリア |



