3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ClosedXML.ReportでExcelにデータを書き込む

Last updated at Posted at 2022-02-11

はじめに

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がらインストール

image.png

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があるなら、あらかじめテンプレートファイルを用意しておくのもあり。
(上記ブックをエクセルで開くと以下のようになる)
image.png

③テンプレートにデータを流し込む

XLTemplateクラスのコンストラクタに、先ほどのブックのオブジェクト、またはテンプレートのExcelファイルがあるならそのパスを渡します。AddVariableメソッドに流し込むデータオブジェクトを渡し、Generateメソッドでデータがエクセルに生成されます。


    // テンプレートを作成
    using (var template = new XLTemplate(wkb))
    {
        // テンプレートにオブジェクトを突っ込む
        template.AddVariable(obj);
        template.Generate();
        // 保存
        template.SaveAs("result.xlsx");

    }

実行すると↓↓↓のようなExcelが出来上がります。
image.png

別の例

上記では、簡単な例を示しましたが、名前をちゃんと定義すれば下記のようにもできます。


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"));
}

image.png

まとめ

ClosedXML.Reportを使うことで、ループを回さなくともExcelにデータを書き込むことができました。
GitHubにサンプルが色々とあるので、参照してみてください。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?