CSVファイルを読み込んでExcelを作りたい。
その時数値によってセルの色を変えたい。
との要望があり、久々にClosedXMLを触りました。
60*30 の区切られたセル範囲を8つ繰り返すものをサンプルとして渡されました。
【案1】書式設定で色を付ける
数値はある範囲でのレベルを示すので、書式設定でカラースケールを使用するのが素直な方法かと思います。
しかしこの手法では数値範囲に対して3色しか振ることができない様です。
今回は3色以上の極を持つカラースケールが必要とのことでしたのでこの手段は使えません。
また、この手法を使った場合、色付けのセルが大量にあると描画に時間がかかります。
スクロールするたびにがくがく重くなってしまいちょっと使いものにならない印象。
どうも表示範囲が変わるたびにExcelで再描画処理が走る様です。
【案2】セルの塗りつぶし色で色を付ける
セルの塗りつぶし色はOpenXMLではForegroundColorとBackGroundColorで色を指定すればOK
こちらの方法で生成したExcelはスクロールしてもスイスイ。
using (XLWorkbook book = new XLWorkbook(savePath, XLEventTracking.Disabled))
{
IXLWorksheet sheet = book.AddWorksheet("sheetName");
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 30; j++)
{
var color = XLColor.AliceBlue;
var cell = sheet.Cell(i,j);
cell.Style.Fill.SetBackgroundColor(color);
cell.Style.Font.FontColor = color;
}
}
book.Save();
}
が、しかし生成に時間がかかる
なぜかSave時点でめちゃめちゃ時間がかかります。
色々と調べてみたところ、セルに色を付けるためには、概ね以下の手順が踏まれていました。
- カラーテーブルに色を登録
- その色で塗りつぶされたセルフォーマットを登録
- 各セルにそのセルフォーマットのIDを指定
最初の時点では1024色使う可能性があり、実際に塗ってみたら500色位になっていました。
この色の登録とセルフォーマットの登録に大半の時間を費やされていました。
このことに気づいて、仕様を調整して64色まで減らしました。
そうするとSaveにかかる時間は大幅に短縮することができました。
気付いたこと
セルの書式設定にある項目をいじると描画に時間がかかるようになります。
- セルサイズに合わせて文字を縮小
- 表示形式
などなど
上記に関連してセルフォーマットを大量に作る場合はSave時点でセル数に比例して(??)時間がかかります。
またClosedXMLのインスタンスも大量に生成されとんでもなくメモリを消費します。