C# で Excel を操作したい。。。
C# でエクセルファイルを操作したい方におすすめの記事です。
エクセルファイルを操作するためのライブラリは「EPPlus」や「SpreadSheetLight」などいくつか存在しますが、この記事では「ClosedXML」を使った操作方法を紹介します。
ClosedXML は C# でエクセルを操作するライブラリの中でも、直感的にかつ簡潔にコードを書くことができるライブラリです。
エクセルの標準的な機能はサポートしているので、ぜひ最後まで読んで参考にしてみてください。
オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
ClosedXMLとは
ClosedXML とは、C# で Excel ファイル(Excel 2007 以降 (.xlsx、.xlsm) )を操作するためのオープンソースのライブラリです。
このライブラリは、新規作成した Excel ファイルまたは既存の Excel ファイルを開いて様々な操作が可能です。
以下に記載しいてるような Excel の標準的な操作はサポートしています。
ClosedXML で出来ること
- Excel ファイルの新規作成
- 既存の Excel ファイルの読み込み
- 値や式の入力
- セルの挿入削除、結合
- セルの書式設定
- シートの追加
- ファイルの保存
- その他(ソートやフィルター等)
C# にはほかにも Excel を操作するライブラリがありますが、直感的にかつ簡潔に書くことができます。サンプルコードを後述していますが、そのコードを見て頂ければそのシンプルさを分かって頂けると思います。
また、 Microsoft の純正 API である「Open XML SDK」のラッパーであり、安心感もあります。
ClosedXML の特徴
- 直感的にかつ簡潔に書ける。
- Microsoft の純正 API である「Open XML SDK」のラッパーである。
- エクセルの標準的な機能や多くの機能をサポートしている。
NuGetからインストールする
ClosedXML は Nuget からプロジェクトへインストールできます。
次の手順でインストールしましょう。
ソリューション エクスプローラーからプロジェクトを選択して右クリックして「NuGet パッケージの管理」を選択します。
NuGetパッケージマネージャー画面で「参照」を選択し、検索欄に「ClosedXML」を入力します。
検索結果の一覧の中にある「ClosedXML」を選択して「インストール」をクリックします。
ClosedXMLの使い方
ここから ClosedXML の使い方をサンプルコードを交えて具体的に紹介しています。
環境
- 統合開発環境:Visual Studio 2022
- フレームワーク:.NET 7.0
- ClosedXMLのバージョン:0.102.1
ClosedXML には主に XMWorkbook クラス、IXLWorksheets クラス、IXLWorksheet クラス、IXLcell クラスの4つのクラスがあります。
Excel と同じようにワークブック(XMWorkbook クラス)があって、その中に複数のシート(IXLWorksheet クラス)が含まれています。シートには行と列があり、文字列や数値が入力できるセル(IXLcell クラス)があります。また、シートを管理するコレクション(IXLWorksheets クラス)があります。
これらのクラスを意識することで ClosedXML による Excel の操作がしやすくなると思います。
名前空間を定義する
「ClosedXML」でエクセルを制御する為に、名前空間に含まれている様々なクラス群を使うので、下記のように名前空間を宣言する必要があります。
using ClosedXML.Excel;
これをしないと、型または名前空間の名前’xxxx’が見つかりませんでした(usingディレクティブまたはアセンブリ参照が指定されていることを確認してください)というエラーメッセージが表示されます。
上記のコードをクラスファイルのヘッダー部分に追加しましょう。
新しいワークブックを作成する
XLWorkbook
のインスタンスを生成することで、空のワークブックが作成されます。
XLWorkbook
のオブジェクトは使い終わったらDispose
します。
下記コードのパターン 2 で紹介している using ステートメントを使うことで、オブジェクトのDispose
がそのスコープを抜けると自動で呼び出されるようになります。 これにより、変数の宣言に対して破棄は自動化されるため、Dispose
の書き忘れによるエラーが無くなります。
// パターン 1
var wb = new XLWorkbook();
try
{
// 何かしらの処理をここに書く
}
finally
{
// finally句でDisposeを呼び出す
wb.Dispose();
}
// パターン 2
using (var wb = new XLWorkbook())
{
// 何かしらの処理をここに書く
}
既存のワークブックファイルを開く
既存のエクセルファイルを開く場合は、XLWorkbook
の引数にファイルパスを指定します。
using (var wb = new XLWorkbook(@"C:\Users\Desktop\test.xlsx"))
{
// 何かしらの処理をここに書く
}
ワークブックを上書き保存する
XLWorkbook.Saveメソッド
既存のエクセルファイルを開いて操作している場合は、Save
メソッドで上書き保存ができます。
using (var wb = new XLWorkbook(@"C:\Users\Desktop\test.xlsx"))
{
// 上書き保存する
wb.Save();
}
新規作成したワークブックに対して、Save
メソッドを実行するとSystem.InvalidOperationException: ‘This is a new file. Please use one of the ‘SaveAs’ methods.’という例外メッセージが表示されます。
using (var wb = new XLWorkbook())
{
wb.Worksheets.Add();
wb.Save();
// Saveメソッドが実行されると、次の例外メッセージが表示されます。
// System.InvalidOperationException: 'This is a new file. Please use one of the 'SaveAs' methods.'
}
この場合はSaveAs
メソッドで名前を付けて保存しましょう。
ワークブックに名前を付けて保存する
XLWorkbook.SaveAsメソッド
ワークブックに名前を付けて保存したい場合は、SaveAs
メソッドの引数にファイルパスを指定します。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
wb.Worksheets.Add();
// test.xlsxとして保存する
wb.SaveAs(@"C:\Users\Desktop\test.xlsx");
}
ワークシートを追加する
IXLWorksheets.Addメソッド
ワークブックを単に新規作成しただけでは、ワークシートが1つもない状態です。そのため、ワークシートを追加する必要があります。
IXLWorksheets.Add
メソッドにはいくつかのオーバーロードがあります。引数なしの場合、最初のワークシートの名前は「Sheet1」になります。メソッドの戻り値は新規作成したワークシートのオブジェクトです。
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add();
}
ワークシート名を指定してワークシートを新規作成したい場合は、引数にワークシート名を指定します。
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("新しいシート名");
}
ワークシートのポジション(エクセルで開いたときのシートタブの並び位置)を指定したい場合は、第2引数に位置を指定します。
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("新しいシート名", 0);
}
既存のワークシートを取得する
XLWorkbook.Worksheetメソッド
既存のワークシートを取得するには、XLWorkbook.Worksheet
メソッドの引数にワークシート名を指定します。存在しないワークシート名を指定された場合、例外がスローされます。
using (var wb = new XLWorkbook())
{
// Sheet1、Sheet2を追加する
wb.Worksheets.Add();
wb.Worksheets.Add();
// Sheet1のワークシートのオブジェクトを取得する
var ws = wb.Worksheet("Sheet1");
}
ワークシートを削除する
IXLWorksheets.Deleteメソッド
ワークシートを削除するには、IXLWorksheets.Delete
メソッドの引数にワークシート名またはワークシートのポジションを指定します。
using (var wb = new XLWorkbook())
{
// Sheet1、Sheet2を追加する
wb.Worksheets.Add();
wb.Worksheets.Add();
// 追加したSheet1を削除する
wb.Worksheets.Delete(1);
}
ワークシートを移動する
IXLWorksheet.Positionプロパティ
ワークブック内のワークシートの順序を並べ替えるには、IXLWorksheet.Position
プロパティを使用します。ワークシートは元の位置から移動して新しい位置になり、それに応じて他のワークシートも移動します。
using (var wb = new XLWorkbook())
{
// Sheet1、Sheet2、Sheet3、Sheet4を追加する
wb.Worksheets.Add();
wb.Worksheets.Add();
wb.Worksheets.Add();
wb.Worksheets.Add();
// Sheet1を3番目に移動する
wb.Worksheet("Sheet1").Position = 3;
}
ワークシートをコピーする
IXLWorksheet.CopyToメソッド
特定のワークシートをコピーする場合には、IXLWorksheet.CopyTo
メソッドを使用します。コピー元のワークシートを選択し、コピーしたワークシートの名前を引数として渡します。
using (var wb = new XLWorkbook())
{
// Sheet1、Sheet2を追加する
wb.Worksheets.Add();
wb.Worksheets.Add();
// Sheet1をコピーして、CopySheetを追加する
var ws = wb.Worksheet("Sheet1");
ws.CopyTo("CopySheet");
}
ワークシートのセルに値を記述する
IXLCell.SetValueメソッド
IXLCell.Valueプロパティ
セルに値をセットするには、IXLCell.SetValue
メソッドを使用する方法とIXLCell.Value
プロパティを使用する方法があります。
IXLCell.SetValue
メソッドを使用する場合は値の記述に加えて、書式設定を続けて行うことが可能です。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// Sheet1のセルA1を指定する
var cell = ws.Cell(1, 1);
// セルに値をセットする
cell.SetValue("TEST");
// 以下でもOK
// cell.Value = "TEST";
// SetValueメソッドで値をセットし、セルの背景を黄色にする
cell.SetValue("TEST")
.Style.Fill.SetBackgroundColor(XLColor.Yellow);
}
実行結果は次のようになります。
また、Range
メソッドや Cells のValue
プロパティもしくはSetValue
メソッドに値を指定することで、範囲内をまとめて値や式、書式をセットすることが可能です。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1~G4セルにまとめて値をセットする
ws.Range(1, 1, 4, 7).SetValue("10");
// 下記でもOK
// ws.Range(1, 1, 4, 7).Value = "10";
}
実行結果は次のようになります。
ワークシートのセルの値を取得する
IXLCell.Valueプロパティ
セルの値を取得するには、IXLCell.Value
プロパティを使用します。IXLCell.Value
プロパティはXLCellValue
型ですが、XLCellValue.ToString()
を使うと文字列としてセルの値を取得できます。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1に値を設定する
ws.Cell(1, 1).SetValue("TEST");
// A1の値を取得する
var value = ws.Cell(1, 1).Value.ToString();
// デバッグへ出力する
Debug.WriteLine(value);
}
実行結果は次のようになります。
TEST
XLCellValue
型には、取得したセルの値の型(文字列、数値、日付等)の判定と、それぞれの形式での値を取得するメソッドが実装されています。
セルの値の型 | セルの値を取得するメソッド |
---|---|
文字列 | GetText |
数値 | GetNumber |
日付 | GetDateTime |
ブーリアン | GetBoolean |
タイムスパン | GetTimeSpan |
型を指定してセルの値を取得したい場合は、次のように型判定を行い、適切なメソッドで取得します。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1に値をセット
ws.Cell(1, 1).SetValue("TEST");
// A1の値を取得する
XLCellValue value = ws.Cell(1, 1).Value;
if (value.IsText)
{
// 文字列型で取得する
string text = value.GetText();
}
else if (value.IsNumber)
{
// 数値型(double)で取得する
double num = value.GetNumber();
}
else if (value.IsDateTime)
{
// 日付型で取得する
DateTime date = value.GetDateTime();
}
else if (value.IsBoolean)
{
// Boolean型で取得する
bool text = value.GetBoolean();
}
else if (value.IsTimeSpan)
{
// TimeSpan型で取得する
TimeSpan text = value.GetTimeSpan();
}
}
ワークシートのセルに式を設定する
- A1形式
IXLCell.SetFormulaA1メソッド
IXLCell.FormulaA1プロパティ - RC形式
IXLCell.SetFormulaR1C1メソッド
IXLCell.FormulaR1C1プロパティ
A1 形式で式を設定する場合は、IXLCell.SetFormulaA1
メソッドまたはIXLCell.FormulaA1
プロパティを使用します。設定できる式は、Excel で使える計算式やセルの参照、関数などが使えます。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1とB1に値を設定する
ws.Cell(1, "A").SetValue(2);
ws.Cell(1, "B").SetValue(3);
// C1に式を設定する
var cell = ws.Cell(1, "C").SetFormulaA1("=A1*B1");
// デバッグへ出力する
Debug.WriteLine(cell.Value.ToString());
}
実行結果は次のようになります。
6
R1C1 形式で式を設定する場合は、IXLCell.SetFormulaR1C1
メソッドまたはIXLCell.FormulaR1C1
プロパティを使用します。R1C1 形式とは、行と列を番号で表す方法です。例えば、セル A1 は R1C1、B1 は R1C2 となります。
R1C1 形式では相対参照を使用することができます。式を設定するセルを基準にして、式で使用するセルのズレを[]で囲んで使用します。
下記のコード(13行目)を例にすると、式を設定する R1C3(C1)が基準となります。R1C1(A1)は列が基準から -2(=1-3)ズレていているので、RC[-2] になります。R1C2(B1)は列が基準から -1(=2-3)ズレているので、RC[-1] になります。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1とB1に値を設定する
ws.Cell(1, 1).SetValue(2);
ws.Cell(1, 2).SetValue(3);
// C1に式を設定する
var cell = ws.Cell(1, 3).SetFormulaR1C1("R1C1*R1C2");
// 下記でもOK(相対参照を使用した例)
// var cell = ws.Cell(1, 3).SetFormulaR1C1("RC[-2]*RC[-1]");
// デバッグへ出力する
Debug.WriteLine(cell.Value.ToString());
}
実行結果は次のようになります。
6
セルのフォントを設定する
IXLCell.Style.Font.SetBoldメソッド
IXLCell.Style.Font.SetFontColorメソッド
IXLCell.Style.Font.SetFontNameメソッド
IXLCell.Style.Font.SetFontSizeメソッド
IXLCell.Style.Font.SetUnderlineメソッド
フォントを設定する場合は、セルを指定してStyle.Font
プロパティでフォントの種類やサイズ、文字色などを指定します。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1に値を設定する
ws.Cell("A1").SetValue("Hello World");
// A1のフォントを設定する
ws.Cell("A1").Style
.Font.SetBold(true) // 太字
.Font.SetFontColor(XLColor.Red) // 文字色
.Font.SetFontName("メイリオ") // フォント名
.Font.SetFontSize(20) // フォントサイズ
.Font.SetUnderline() // 下線
.Fill.SetBackgroundColor(XLColor.LightGray); // 背景
}
実行結果は次のようになります。
セルに罫線を引く
IXLCell.Style.Border.SetxxxxBorderメソッド
※xxxxは罫線を引く場所を指定します。
罫線を引く場合は、セルを指定してStyle.Border
プロパティで罫線を引く場所、罫線の種類などを指定します。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
//セルの4箇所に罫線を引く
ws.Cell("B2").Style.Border.SetOutsideBorder(XLBorderStyleValues.Thin); //細線
ws.Cell("B4").Style.Border.SetOutsideBorder(XLBorderStyleValues.Thick); //太線
ws.Cell("D2").Style.Border.SetOutsideBorder(XLBorderStyleValues.Dotted); //点線
ws.Cell("D4").Style.Border.SetOutsideBorder(XLBorderStyleValues.Medium); //中太線
//部分罫線を引く
ws.Cell("F2").Style.Border.SetTopBorder(XLBorderStyleValues.Thin); //上だけ
ws.Cell("F4").Style.Border.SetBottomBorder(XLBorderStyleValues.Thin); //下だけ
ws.Cell("H2").Style.Border.SetLeftBorder(XLBorderStyleValues.Thin); //左だけ
ws.Cell("H4").Style.Border.SetRightBorder(XLBorderStyleValues.Thin); //右だけ
}
実行結果は次のようになります。
セルの書式設定を行う
IXLCell.Style.DateFormat.SetFormatメソッド
IXLCell.Style.NumberFormat.SetFormatメソッド
セルの書式を設定するには、Style.DateFormat
のSetFormat
メソッドやStyle.NumberFormat
のSetFormat
メソッドを使用します。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
// A1に値を設定する
var cell1 = ws.Cell("A1").SetValue(0.103);
// 数値の書式を設定する
cell1.Style.DateFormat.Format = "0.0%;▲0.0%;- ";
// A2に値を設定する
var cell2 = ws.Cell("A2").SetValue(new DateTime(2023, 11, 2));
// 数値の書式を設定する
cell2.Style.DateFormat.Format = "yyyy-MM-dd";
wb.SaveAs("sample.xlsx");
}
実行結果は次のようになります。
条件付き書式の設定を行う
IXLCell.AddConditionalFormatメソッド
セルに条件付き書式を設定するには、AddConditionalFormat
メソッドを使用します、
AddConditionalFormat
メソッドは、条件を1個追加する毎に呼び出す必要があります。また、WhenEquals
メソッドは完全一致条件を追加します。また、範囲を指定するのであればWhenBetween
、部分一致であればWhenContains
、空白指定であればWhenIsBlank
等、IXLConditionalFormat
クラス(AddConditionalFormat
メソッド戻り値)に各条件指定方法のメソッドが用意されています。
using (var wb = new XLWorkbook())
{
// Sheet1を追加する
var ws = wb.Worksheets.Add();
var cell1 = ws.Cell("A1");
var cell2 = ws.Cell("A2");
// A1とA2に条件付き書式を設定する。
// 値が「OK」なら背景色を緑、値が「NG」なら背景色を赤」にする。
cell1.AddConditionalFormat().WhenEquals("OK").Fill.SetBackgroundColor(XLColor.LightGreen);
cell2.AddConditionalFormat().WhenEquals("NG").Fill.SetBackgroundColor(XLColor.BrickRed);
// A1とA2に値を設定する
cell1.SetValue("OK");
cell2.SetValue("NG");
wb.SaveAs("sample.xlsx");
}
実行結果は次のようになります。
まとめ
今回は C# で ClosedXML を利用したエクセルの操作方法について解説しました。
Excel のインストール不要で、ClosedXML のサンプルも豊富にあるため扱いやすいライブラリです。
エクセルの読み書きやセルの書式設定など基本的な操作は網羅されているので、エクセルを扱う際は利用してみてはいかがでしょうか。
以上、最後まで読んで頂きありがとうございました。