ClosedXMLを使って、超高速にリスト形式の帳票を作成する

xlsx 形式な Excel ファイルを高速に読み込めたということは、ひょっとして高速に書き込めるのでは?と思って書いてみたのがこれ。
あらかじめ Excel で作ったテンプレートを用意しおいて、行を追加しているだけ。行数分コピーしているのは3行目のセル/行に書式が設定してあるから。こうしておくと罫線とか色とかフォントとかをコードで指定しなくて済む。

public void 印刷()
{
    var path = AppDomain.CurrentDomain.BaseDirectory + @"template\協力会社一覧.xlsx";
    using (var wb = new XLWorkbook(path))
    {
        var sh = wb.Worksheets.First();
        // あらかじめ行数分用意しておく
        var rg = sh.Row(3);
        for (int i = 0; i < this.Items.Count - 1; i++)
        {
            rg.CopyTo(sh.Row(i + 4));
        }

        int r = 2;
        foreach (var it in this.Items)
        {
            sh.Cell(r, 1).Value = it.業者ID;
            sh.Cell(r, 2).Value = it.業者名称;
            sh.Cell(r, 3).Value = it.担当者;
            sh.Cell(r, 4).Value = it.役職;
			// 途中は省略
            r++;
        }
        // テンポラリファイルに保存
        var temp = System.IO.Path.GetTempFileName() + ".xlsx";
        wb.SaveAs(temp);
        System.Diagnostics.Debug.WriteLine(temp);
        // テンポラリファイルを開いて印刷
        var xapp = new Excel.Application();
        var xwb = xapp.Workbooks.Open(temp);
        var xsh = xwb.Worksheets[1] as Excel.Worksheet;
        xsh.PrintOutEx();
        xwb.Close(false);
        xapp.Quit();
        System.IO.File.Delete(temp);
    }
}

どうやら、ClosedXML には印刷機能がないらしいので、印刷のほうは Microsoft.Office.Interop.Excel を呼び出している。それでもスピードは体感で10倍以上にはなる。書き込みも相当スピードアップされるらしい。
実はレポート出力用に ClosedXML.Report https://github.com/ClosedXML/ClosedXML.Report というのもあるのだが、行単位の一覧程度ならばこの方式で十分だろう。表形式じゃないレポート形式の場合は、別途変換してみよう。

実行例

テンプレート用の Excel ファイルはこんな感じで1行だけ作っておく。フォントの設定とか文字列の折り返し、罫線などをあらかじめ Excel 上で設定してあるので、3行目を CopyTo するだけでよい.

これを Excel COM を使って印刷する。OpenXML/ClosedXML が印刷機能を持っていればよいのだが、どうやら XML の読み書きの機能だけでレンダリングはないらしい。実際は PDF に落とせばよい(PDFから印刷する方法もあるので)ので、iText とかの PDF 出力を使えばよいらしいのだが、まあ、印刷はプリンタ独自の設定も含むことがあるので Excel COM を使ったほうがよいだろう。

Windows 10 で印刷した結果がこちら。Excel からの出力先を PDF にすると手軽に PDF ファイルの落とせる(Excel のエクスポート機能を使ってもよい)。

帳票は Excel 形式で残したほうがよい場合と、Excel 形式のような「編集できる形式」では残してはいけない場合がある。編集不可にしたいときは PDF にするのが常なのだが、これは税務処理などで金額の修正があると困る場合によく使われる。Excel 形式のまま残すと改竄されてしまうので、わざわざ PDF で残すのだ。もっとも、詳しい人ならば暗号化していないと PDF の内部で修正が出来てしまうのだが…まあ、一般的には「PDF だと修正できない」ので大丈夫と思ってよい。きちんとやる場合は PDF に暗号をかけるか、Excel 形式のままハッシュ値を保存して暗号化(いわゆるブロックチェーンな方法)をとればよい。

 

カテゴリー: C# パーマリンク