「ClosedXML - Excelファイルの操作」の版間の差分
細 (Wiki がページ「Excelファイルを操作する方法(C Sharp)」を「ClosedXML - Excelファイルの操作」に、リダイレクトを残さずに移動しました) |
細 (文字列「<source」を「<syntaxhighlight」に置換) |
||
46行目: | 46行目: | ||
== Closed XMLの使用方法 == | == Closed XMLの使用方法 == | ||
ここからは、Excelファイルを操作する方法を簡単に記載する。(詳細は前述のドキュメントを参照すること)<br> | ここからは、Excelファイルを操作する方法を簡単に記載する。(詳細は前述のドキュメントを参照すること)<br> | ||
< | <syntaxhighlight lang="c#"> | ||
const string ExcelFilePath = @"sample.xlsx"; | const string ExcelFilePath = @"sample.xlsx"; | ||
81行目: | 81行目: | ||
== Excelファイルのデータを読み書きする == | == Excelファイルのデータを読み書きする == | ||
上記のサンプルコードで作成したExcelファイルを読み込み、セルのデータを読み書きするサンプルコードを以下に記述する。<br> | 上記のサンプルコードで作成したExcelファイルを読み込み、セルのデータを読み書きするサンプルコードを以下に記述する。<br> | ||
< | <syntaxhighlight lang="c#"> | ||
const string ExcelFilePath = ".\\sample.xlsx"; | const string ExcelFilePath = ".\\sample.xlsx"; | ||
122行目: | 122行目: | ||
<br> | <br> | ||
以下のサンプルコードではコレクションを挿入したが、DataTableにデータを挿入するときも同様にInsertDataメソッドを使用する。<br> | 以下のサンプルコードではコレクションを挿入したが、DataTableにデータを挿入するときも同様にInsertDataメソッドを使用する。<br> | ||
< | <syntaxhighlight lang="c#"> | ||
const string ExcelFilePath = @"sample.xlsx"; | const string ExcelFilePath = @"sample.xlsx"; | ||
177行目: | 177行目: | ||
そのセル範囲からコレクションを生成するには、LINQのSelect拡張メソッドを使用する。<br> | そのセル範囲からコレクションを生成するには、LINQのSelect拡張メソッドを使用する。<br> | ||
また、DataTableに変換するのも簡単である。<br> | また、DataTableに変換するのも簡単である。<br> | ||
< | <syntaxhighlight lang="c#"> | ||
const string ExcelFilePath = ".\\sample.xlsx"; | const string ExcelFilePath = ".\\sample.xlsx"; | ||
2021年11月21日 (日) 09:33時点における版
概要
Microsoft Office(Word / Excel / PowerPoint)のファイルをプログラムから操作するために、Open XML SDKがMicrosoftから提供されているが、
汎用的な構造になっているため、特にExcelファイルのデータや書式を扱うには煩雑になっている。
Excelファイルのみを扱う場合、サードパーティ製のClosed XMLを使用するとよい。
ここでは、そのClosed XMLの使用方法を記載する。
Closed XMLとは
Open XML形式のExcelファイル(拡張子 : xlsx / xlsm)を読み書きするためのライブラリである。
MicrosoftのOpen XML SDKをラップし、Excelに特化することで使用しやすいライブラリになっている。
ソースコードはGitHubで公開されている。(MITライセンス)
- できること
- Open XML形式のExcelファイルの編集と数式の実行。
- Open XML形式のExcelファイルの実体は、XMLファイルを格納したzipアーカイブである。
- そのアーカイブを作成したり、アーカイブ内のデータを読み書きしたりできる。
- セルのデータや数式などの読み書きや書式の設定などが可能である。
- 更に、Excelの主な関数を独自に実行する機能も持っている。
- できないこと
- Excelの機能を利用すること。
- Open XML形式のExcelファイルの読み書きは可能だが、Excelアプリの機能を利用しているわけではない。
- Excelアプリの機能、例えば、グラフを生成したりはできない。
- ただし、Open XML SDKとは異なり、Excelの主な関数はサポートされている。
- サポートされているプラットフォーム
- .NET Framework 4.0以降
- .NET Standard 2.0以降
- .NET Standard 2.0で動作するということは、それをサポートしている以下のプラットフォームからも利用できる。
- .NET Core(ASP.NET Core) 2.0以降
- UWP 10.0.16299(1709)~
- Xamarin.iOS 10.14以降
- Xamarin.Android 8.0以降
Closed XMLのドキュメントは、ClosedXMLのWikiで公開されている。
ここでは、Excelファイルを操作する例をいくつか記載するだけなので、詳しい使用方法はこのドキュメントを参照すること。
Closed XMLの導入方法
GitHubからソースコードをダウンロードしてビルドしてもよいが、バイナリファイルがNuGetで公開されている。
Visual Studioでプロジェクトを作成して、NuGetでClosedXmlを検索してインストールする。
Open XML SDKなど、いくつかの必要なパッケージが一緒にインストールされる。
Closed XMLの使用方法
ここからは、Excelファイルを操作する方法を簡単に記載する。(詳細は前述のドキュメントを参照すること)
<syntaxhighlight lang="c#"> 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ファイルを保存しました。"); } </source>
Excelファイルのデータを読み書きする
上記のサンプルコードで作成したExcelファイルを読み込み、セルのデータを読み書きするサンプルコードを以下に記述する。
<syntaxhighlight lang="c#"> 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(); } } </source>
コレクションやDataTableの使用
Closed XMLは、コレクションやLINQなどと相性が良い。
コレクションやDataTableオブジェクト(System.Data名前空間)を簡単にワークシートに挿入できる。
以下のサンプルコードは、コレクションを挿入している例である。
データを挿入するInsertDataメソッドは、挿入したセルの範囲を返すので、続けてその範囲のセルを処理しやすい。
また、その範囲から特定の行を抽出するには、ラムダ式で条件を指定できる。
以下のサンプルコードではコレクションを挿入したが、DataTableにデータを挿入するときも同様にInsertDataメソッドを使用する。
<syntaxhighlight lang="c#"> 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("ワークシートを追加しました。"); } </source>
上記で作成したExcelファイルを読み取る。
何らかのデータや数式が入力されているセルの範囲を取得するRangeUsedメソッドがあるので、セルの位置を指定せずに簡単にデータ範囲を取り出せる。
そのセル範囲からコレクションを生成するには、LINQのSelect拡張メソッドを使用する。
また、DataTableに変換するのも簡単である。
<syntaxhighlight lang="c#"> 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]})"); } } } </source>