はじめに
ClosedXMLをつかってExcelを操作するなどの記事はいくつか散見しますが、「ClosedXML.Report」の使い方を解説した記事はなかなか無いので、本記事で少し解説しようと思います。
ClosedXML.Reportとは
「ClosedXMLとは」の説明と被るので、詳しくは他の記事等を参照してください。
簡単に言うと、ExcelがインストールされていなくてもExcelファイルを操作できるライブラリです。
通常は、COMコンポーネットを参照して使うのですが、それにはExcelがインストールされている必要があります。ClosedXMLではその必要がなくなります。
何が違う?
ClosedXMLとClosedXML.Reportで何が違うのかについてですが、例えばテーブルデータをExcelに書き込む場合、下記にのように、行と列のForループを回して各セルに入力するように実装するかと思いますが、ClosedXML.Reportではその必要がなくなり、より効率的になります。
何より、安易に何重にもループを回したりするのは個人的に「んー...」と思ってしまいます。わかりやすいので悪いことではないですが。
// 普通にClosedXMLだけ使う場合
var wkb = new XLWorkbook();
var wsh = wkb.Worksheet("Sheet1");
var data = new[]
{
Enumerable.Range(1,5).ToArray(),
Enumerable.Range(2,5).ToArray(),
Enumerable.Range(3,5).ToArray(),
};
for (int i = 0; i < data.Count(); i++)
{
for (int j = 0; j < data[i].Count(); j++)
{
wsh.Cell(i + 1, j + 1).Value = data[i][j];
}
}
ClosedXML.Reportを使う
では、本題です。本記事ではExcelがインストールされていないことを前提に、話を進めます。
あってもOKです。
まずはNuGetがらインストール
using ClosedXML.Excel;
using ClosedXML.Report;
テンプレートとなるExcelファイルを生成する
Excelにデータを流し込むオブジェクトを用意する。オブジェクトは下記の例だと匿名型を使ってはいるが、普通にクラスを用意して、使うこともできる。
次にテンプレートとなるブックを生成する。オブジェクトのValuesプロパティはコレクションなので、セルA1に"{{item}}"と入力しておく(値が一つなら、"{{item.Values}}"でOK)。
さらに、ブックに名前を定義しておく。Dataプロパティの参照範囲とValuesプロパティの参照範囲を定義する。
これで、準備OK。
// 匿名クラス(ちゃんとクラスを作ってもよい)
var obj = new
{
Data = new[]
{
new { Values = Enumerable.Range(1,5) },
new { Values = Enumerable.Range(2,5) },
new { Values = Enumerable.Range(3,5) }
}
};
// ブックを生成
using (var wkb = new XLWorkbook())
{
// シート追加
var wsh = wkb.Worksheets.Add("Sheet1");
//セルに入力
wsh.Cell("A1").Value = "{{item}}";
// ブックにプロパティの名前を定義する。
wkb.NamedRanges.Add("Data", wsh.Ranges("A1:B2"));
wkb.NamedRanges.Add("Values", wsh.Ranges("A1"));
}
Excelがあるなら、あらかじめテンプレートファイルを用意しておくのもあり。
(上記ブックをエクセルで開くと以下のようになる)
③テンプレートにデータを流し込む
XLTemplateクラスのコンストラクタに、先ほどのブックのオブジェクト、またはテンプレートのExcelファイルがあるならそのパスを渡します。AddVariableメソッドに流し込むデータオブジェクトを渡し、Generateメソッドでデータがエクセルに生成されます。
// テンプレートを作成
using (var template = new XLTemplate(wkb))
{
// テンプレートにオブジェクトを突っ込む
template.AddVariable(obj);
template.Generate();
// 保存
template.SaveAs("result.xlsx");
}
別の例
上記では、簡単な例を示しましたが、名前をちゃんと定義すれば下記のようにもできます。
var obj = new
{
ColumnNames = new[] { "名前", "年齢", "性別" },
Data = new[]
{
new { Name = "颯太", Age = 20, Sex = "男性" },
new { Name = "結衣", Age = 18, Sex = "女性" },
new { Name = "海斗", Age = 22, Sex = "男性" },
new { Name = "香織", Age = 21, Sex = "女性" },
}
};
// ブックを生成
using (var wkb = new XLWorkbook())
{
var wsh = wkb.Worksheets.Add("Sheet1");
wsh.Cell("A1").Value = "{{item}}";
wsh.Cell("A2").Value = "{{item.Name}}";
wsh.Cell("B2").Value = "{{item.Age}}";
wsh.Cell("C2").Value = "{{item.Sex}}";
wkb.NamedRanges.Add("Data", wsh.Ranges("A2:C3"));
wkb.NamedRanges.Add("ColumnNames", wsh.Ranges("A1"));
}
まとめ
ClosedXML.Reportを使うことで、ループを回さなくともExcelにデータを書き込むことができました。
GitHubにサンプルが色々とあるので、参照してみてください。