ClosedXML - Excelファイルの操作
概要
ClosedXMLは、Microsoft Excelファイルの作成、読み取り、編集を簡単に行うことができるように設計されている。
ClosedXMLの主な特徴は、その使いやすさにある。
開発者は、Excelファイルの操作をプログラム的に行う場合に、複雑なExcel Object Modelを直接扱う必要がない。
代わりに、ClosedXMLは直感的なAPIを提供しており、これにより開発者は効率的にExcelファイルを操作することができる。
このライブラリを使用すると、新しいワークブックの作成、既存のワークブックの開封、ワークシートの追加や削除、セルの書式設定、数式の追加、グラフや画像の挿入等が可能である。
また、大量のデータを扱う際のパフォーマンスも考慮されており、メモリ効率の良い操作が可能である。
ClosedXMLの大きなメリットの1つは、Microsoft Office製品がインストールされていないPCでも動作することである。
これは、サーバ環境でのExcelファイル操作を可能にして、多くの企業システムで重要な機能となっている。
セキュリティの観点からもClosedXMLは優れており、ファイルの操作がプログラム的に行われるため、マクロを含むExcelファイルによるセキュリティリスクを軽減できる。
ClosedXMLの使用例としては、財務レポートの自動生成、大量のデータの分析と視覚化、テンプレートベースの文書生成等が挙げられる。
これらのタスクは、ビジネスアプリケーションでよく必要とされるものである。
このライブラリは活発に開発が続けられており、コミュニティからの支援も豊富なため、バグ修正や新機能の追加が定期的に行われており、最新のExcel機能にも対応している。
ただし、ClosedXMLにも制限はある。
例えば、一部の高度なExcel機能はサポートされていない場合がある。
また、非常に大きなファイルを扱う場合には、メモリ使用量に注意が必要となる。
ClosedXMLはC#開発者にとって、Excelファイル操作を効率的に行うための強力なツールである。
その使いやすさ、豊富な機能、そして堅牢性により、多くのプロジェクトで重要な役割を果たしている。
Closed XMLとは
Open XML形式のExcelファイル(拡張子 : xlsx / xlsm)を読み書きするためのライブラリである。
MicrosoftのOpen XML SDKをラップし、Excelに特化することで使用しやすいライブラリになっている。
Closed XMLのソースコードは、GitHubで公開されている。
また、Closed XMLのライセンスは、MITライセンスである。
Closed XMLで可能なこと
- Open XML形式のExcelファイルの作成と編集
- セルデータの読み書き
- 数値、文字列、日付等の各種データ型
- 複雑な数式の挿入と評価
- セルの書式設定
- フォント
- 色
- 罫線
- 背景色
- ワークシートの操作
- 追加、削除、名前変更、コピー
- 行や列の挿入、削除、非表示設定
- Excelの主要関数のサポート
- SUM, AVERAGE, VLOOKUP, IF等
- 大量データの高速処理
- テンプレートベースの文書生成
- 基本的な条件付き書式の適用
- ハイパーリンクの挿入と管理
- 印刷設定の調整(ページ設定、印刷範囲など)
Closed XMLで実行できないこと
- Excelアプリケーションの直接操作
- マクロやVBAコードの実行・編集
- 複雑なグラフや図表の新規作成
- ピボットテーブルの新規作成や高度な編集
- 一部の高度なExcel機能
- 複雑な条件付き書式
- スパークライン
- 高度なデータ検証ルール
- 外部データソースとの動的連携
- リアルタイムデータ更新
- Excelアドインの使用
- 複雑な画像操作や図形の作成
- コメントの詳細な管理や高度な編集
※注意
上記は、Closed XMLは継続的に更新されているため、一部の機能は将来のバージョンで追加される可能性がある。
サポートされているプラットフォーム
以下に示すプラットフォームサポートにより、Closed XMLは幅広い.NET環境で使用できる柔軟性の高いライブラリとなっている。
デスクトップアプリケーション、Webアプリケーション、モバイルアプリケーション、ゲーム開発まで、様々な種類のプロジェクトでExcelファイルの操作が可能である。
- .NET Core 2.0以降 / .NET 5以降
- .NET Framework 4.5以降(4.0ではなく4.5からのサポート)
- .NET Standard 2.0以降
.NET Standard 2.0のサポートにより、以下のプラットフォームでも利用可能である。
- ASP.NET Core 2.0以降
- UWP(Universal Windows Platform)10.0.16299 (Fall Creators Update、1709) 以降
- Xamarin.iOS 10.14以降
- Xamarin.Android 8.0以降
- Xamarin.Mac 3.8以降
- Unity 2018.1以降 (ゲーム開発プラットフォームとしても利用可能)
※注意
プラットフォームのバージョンは、Closed XMLのバージョンによって変更される可能性がある。
最新の対応状況は、Closed XMLの公式ドキュメントやGithubリポジトリで確認することを推奨する。
また、一部の機能は、特定のプラットフォームでのみ利用可能な場合がある。
Closed XMLのドキュメントは、ClosedXMLのGithubで公開されている。
Closed XMLの詳細を知りたい場合は、公式ドキュメントを参照すること。
Closed XMLの導入方法
RiderまたはVisual StudioからNuGetを使用して、ClosedXmlをインストールする。
- Riderの場合
- [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
- メイン画面下部にある[パッケージ]タブからClosedXMLと入力して検索する。
- メイン画面下部の右にある[+]ボタンを押下して、Closed XMLをインストールする。
また、Closed XMLのGitHubからソースコードをダウンロードして、ビルドおよびインストールすることもできる。
Closed XMLをインストールする時、Open XML SDK等のいくつかの必要なパッケージが同時にインストールされる。
Excelファイルの作成
以下の例では、Excelファイルおよびシートを新規作成して、A1セル〜A3セルに値および式を入力している。
また、A3セルの背景色を塗りつぶして、書式を変更している。
const string ExcelFilePath = @"sample.xlsx";
// Excelファイルの作成
using (var workbook = new XLWorkbook())
{
// ワークシートの追加
using (var worksheet = workbook.Worksheets.Add("サンプルシート1"))
{
// セルに値や式を代入
worksheet.Cell("A1").Value = 10;
worksheet.Cell("A2").SetValue(20);
worksheet.Cell("A3").FormulaA1 = "SUM(A1:A2)";
// セルに書式を設定
var sumCellStyle = worksheet.Cell("A3").Style;
sumCellStyle.Fill.BackgroundColor = XLColor.Red; // 塗りつぶし
sumCellStyle.NumberFormat.Format = "#,##0.00"; // 数値の書式
// 以下に示すように、メソッドチェーンでも記述することができる
//worksheet.Cell("A3").SetFormulaA1("SUM(A1:A2)")
// .Style.Fill.SetBackgroundColor(XLColor.Red)
// .NumberFormat.SetFormat("#,##0.00");
// ワークブックを保存する
workbook.SaveAs(ExcelFilePath);
}
Console.WriteLine(@"Excelファイルを保存しました");
}
Excelファイルのデータを読み書きする
上記のサンプルコードで作成したExcelファイルを読み込み、セルのデータを読み書きするサンプルコードを以下に記述する。
const string ExcelFilePath = ".\\sample.xlsx";
// Excelファイルを開く
using (var workbook = new XLWorkbook(ExcelFilePath))
{
// ワークシートの取得
using (var worksheet = workbook.Worksheet("サンプルシート1"))
{
// 位置を指定してセルを取得
var cellA1 = worksheet.Cell("A1");
var cellA2 = worksheet.Cell(2, "A"); // 行番号と列名でも指定可能
var cellA3 = worksheet.Cell(3, 1); // 行番号と列番号でも指定可能
Console.WriteLine($"A1: {cellA1.GetValue<int>()}"); // 出力 : A1 = 10
Console.WriteLine($"A2: {cellA2.GetValue<int>()}"); // 出力 : A2 = 20
Console.WriteLine($"A3(値): {cellA3.GetValue<int>()}"); // 出力 : A3(値) = 30
Console.WriteLine($"A3(数式): {cellA3.FormulaA1}"); // 出力 : A3(数式) = SUM(A1:A2)
// セルA1の値を書き換える
cellA1.Value = 15;
Console.WriteLine($"A1の値を{cellA1.GetValue<int>()}に書き換えました。"); // 出力 : A1の値を15に書き換えました。
Console.WriteLine($"A3の値は{cellA3.GetValue<int>()}に変わりました。"); // 出力 : A3の値は35に変わりました。
// ワークブックを保存する
workbook.Save();
}
}
コレクションやDataTableの使用
Closed XMLは、コレクションやLINQなどと相性が良い。
コレクションやDataTableオブジェクト(System.Data名前空間)を簡単にワークシートに挿入できる。
以下のサンプルコードは、コレクションを挿入している例である。
データを挿入するInsertDataメソッドは、挿入したセルの範囲を返すので、続けてその範囲のセルを処理しやすい。
また、その範囲から特定の行を抽出するには、ラムダ式で条件を指定できる。
以下のサンプルコードではコレクションを挿入したが、DataTableにデータを挿入するときも同様にInsertDataメソッドを使用する。
const string ExcelFilePath = @"sample.xlsx";
// Excelファイルに貼り付けたいデータ
// 例として、ここでは今月の日付と曜日のコレクションを用意する
List<(DateTime, string)> days = new List<(DateTime, string)>();
var firstDayOfThisMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
int daysInThisMonth = DateTime.DaysInMonth(firstDayOfThisMonth.Year, firstDayOfThisMonth.Month);
for (int i = 0; i < daysInThisMonth; i++)
{
var d = firstDayOfThisMonth.AddDays(i);
days.Add((d, d.DayOfWeek.ToString()));
}
// Excelファイルを開く
using (var workbook = new XLWorkbook(ExcelFilePath))
{
// ワークシートの追加
using (var worksheet = workbook.Worksheets.Add("サンプルシート2"))
{
// タイトル行
var cellA1 = worksheet.Cell("A1");
cellA1.Value = "今月のカレンダー";
cellA1.Style.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center)
.Font.SetFontName("Meiryo")
.Font.SetBold(true)
.Font.SetFontColor(XLColor.White)
.Fill.SetBackgroundColor(XLColor.FromArgb(0x00A2E8));
// セルの連結
worksheet.Range("A1:B1").Merge();
// ワークシートに日付と曜日のコレクションを挿入
var calendarRange = worksheet.Cell("A2").InsertData(days);
// 日曜日の行を抽出して使用しているセルの背景を赤に変更
var sundayRows = calendarRange.Rows(r => r.Cell(1).GetDateTime().DayOfWeek == 0);
foreach (var r in sundayRows)
{
r.CellsUsed().Style.Fill.BackgroundColor = XLColor.Red;
}
// ワークブックの保存
workbook.Save();
}
Console.WriteLine("ワークシートを追加しました。");
}
上記で作成したExcelファイルを読み取る。
何らかのデータや数式が入力されているセルの範囲を取得するRangeUsedメソッドがあるので、セルの位置を指定せずに簡単にデータ範囲を取り出せる。
そのセル範囲からコレクションを生成するには、LINQのSelect拡張メソッドを使用する。
また、DataTableに変換するのも簡単である。
const string ExcelFilePath = ".\\sample.xlsx";
// Excelファイルを開く
using (var workbook = new XLWorkbook(ExcelFilePath))
{
// ワークシートの取得
using (var worksheet = workbook.Worksheet("サンプルシート2"))
{
// データや数式が入力されているセルの範囲
var rangeUsed = worksheet.RangeUsed();
Console.WriteLine($"使用中のセル範囲:{rangeUsed.FirstCell().Address}~{rangeUsed.LastCell().Address}");
// 1列目がDateTime型の行のみを取得してコレクションに変換
IEnumerable<(DateTime,string)> data = rangeUsed.Rows(r => r.Cell(1).DataType == XLDataType.DateTime)
.Select(r => (r.Cell(1).GetDateTime(), r.Cell(2).GetString()));
// 最初の7個を表示
// 出力 : 10/1(Monday) 10/2(Tuesday) 10/3(Wednesday) 10/4(Thursday) 10/5(Friday) 10/6(Saturday) 10/7(Sunday)
foreach (var (d, s) in data.Take(7))
{
Console.WriteLine($"{d:M/d}({s})");
}
// DataTableへの変換もサポート
System.Data.DataTable dataTable = rangeUsed.CreateTable().AsNativeDataTable();
// 8個目から7個を表示
// 出力 : 10/8(Monday) 10/9(Tuesday) 10/10(Wednesday) 10/11(Thursday) 10/12(Friday) 10/13(Saturday) 10/14(Sunday)
foreach(System.Data.DataRow r in dataTable.Select().Skip(7).Take(7))
{
Console.WriteLine($"{r[0]:M/d}({r[1]})");
}
}
}