ClosedXML - Excelファイルの操作

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

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を使用して、Closed XMLをインストールする。

  • Riderの場合
    1. [ツール]メインメニュー - [Nuget] - [ソリューション の Nuget パッケージを管理] (または、[<プロジェクト名> の Nuget パッケージを管理])を選択する。
    2. メイン画面下部にある[パッケージ]タブからClosedXMLと入力して検索する。
    3. メイン画面下部の右にある[+]ボタンを押下して、Closed XMLをインストールする。


また、Closed XMLのGithubからソースコードをダウンロードして、ビルドおよびインストールすることもできる。

Closed XMLをインストールする時、Open XML SDK等のいくつかの必要なパッケージが同時にインストールされる。


Excelファイルの作成

以下の例では、Excelファイルおよびシートを新規作成している。

  • Open XML形式のExcelファイルの作成と編集
    new XLWorkbook()を使用して新しいワークブックを作成する。
    workbook.Worksheets.Add("サンプルシート")でワークシートを追加する。
    workbook.SaveAs("sample.xlsx")でファイルを保存する。
    既存のファイルを開く場合は、new XLWorkbook("サンプル.xlsx")を使用する。


 using System;
 using ClosedXML.Excel;
 
 const string ExcelFilePath = @"sample.xlsx";
 
 // Excelファイルの作成
 using (var workbook = new XLWorkbook())
 {
    // ワークシートの追加
    using (var worksheet = workbook.Worksheets.Add("サンプルシート"))
    {
       // 何らかの処理
 
       // ワークブックを保存する
       workbook.SaveAs(ExcelFilePath);
    }
 
    Console.WriteLine(@"Excelファイルを保存しました");
 
    // 保存したファイルを開いて編集
    using (var workbook = new XLWorkbook("サンプル.xlsx"))
    {
       var worksheet = workbook.Worksheet(1);
 
       // 何らかの処理
  
       // 変更を保存
       workbook.Save();
    }
 }



セルデータの読み書き

以下の例では、Open XML形式のExcelファイルにおいて、セルの値の設定、読み取り、数式の挿入、ファイルの保存と再編集等を行っている。

  • セルデータの読み書き
    • 書き込み
      worksheet.Cell("A1").Value = "文字列" のように、Cellメソッドを使用してセルを指定して、Valueプロパティに値を代入する。
    • 読み取り
      var cellValue = worksheet.Cell("A2").Value のように、Valueプロパティを使用してセルの値を取得する。


  • 数値、文字列、日付等の各種データ型
    • 文字列
      worksheet.Cell("A1").Value = "文字列"
    • 数値
      worksheet.Cell("A2").Value = 123
    • 日付
      worksheet.Cell("A3").Value = DateTime.Now


  • 複雑な数式の挿入と評価
    • 基本的な数式
      worksheet.Cell("B1").FormulaA1 = "=SUM(A1:A3)"
    • 条件付き数式
      worksheet.Cell("C1").FormulaA1 = "=IF(A2>100, \"高い\", \"低い\")"


また、大量のデータを扱う場合は、パフォーマンスを考慮したアプローチ (例: バッチ処理) を検討する必要がある。

 using System;
 using ClosedXML.Excel;
 
 class Program
 {
    static void Main(string[] args)
    {
       // 新しいExcelワークブックを作成
       using (var workbook = new XLWorkbook())
       {
          var worksheet = workbook.Worksheets.Add("サンプルシート");
 
          // セルデータの書き込み
          worksheet.Cell("A1").Value = "文字列";
          worksheet.Cell("A2").Value = 123;           // 数値
          worksheet.Cell("A3").Value = DateTime.Now;  // 日付
 
          // 数式の挿入
          worksheet.Cell("B1").FormulaA1 = "=SUM(A1:A3)";
 
          // セルのスタイル設定
          var cell = worksheet.Cell("A1");
          cell.Style.Font.Bold = true;
          cell.Style.Fill.BackgroundColor = XLColor.LightBlue;
 
          // セルの値を読み取り
          var cellValue = worksheet.Cell("A2").Value;
          Console.WriteLine($"A2セルの値: {cellValue}");
 
          // 複雑な数式の挿入
          worksheet.Cell("C1").FormulaA1 = "=IF(A2>100, \"高い\", \"低い\")";
 
          // セルに書式を設定
          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("サンプル.xlsx");
       }
 
       // 保存したファイルを開いて編集
       using (var workbook = new XLWorkbook("サンプル.xlsx"))
       {
          var worksheet = workbook.Worksheet(1);
 
          // 既存のデータを読み取り
          var a1Value = worksheet.Cell("A1").Value;
          Console.WriteLine($"A1セルの値: {a1Value}");
 
          // 新しいデータを追加
          worksheet.Cell("D1").Value = "新しいデータ";
 
          // 変更を保存
          workbook.Save();
       }
 
       Console.WriteLine("処理が完了しました。");
    }
 }



コレクションや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]})");
       }
    }
 }