C#でClosedXMLを使用してExcelに画像を追加する処理をしていた際、なぜかWorkbookの保存時にObjectDisposedExceptionが発生するという事態になりました。

以下のようなコードです

            using (XLWorkbook wb = new XLWorkbook(filePath))
            {
                IXLWorksheet ws_src = wb.Worksheet("Template");

                using (IXLWorksheet ws = ws_src.CopyTo("1"))
                {
                    var image = ws.AddPicture(imagePath1);
                    image.MoveTo(ws.Cell(3, 3).Address);
                    image.Scale(.5);

                    image = ws.AddPicture(imagePath2);
                    image.MoveTo(ws.Cell(20, 3).Address);
                    image.Scale(2);

                }

                using (IXLWorksheet ws = ws_src.CopyTo("2"))
                {
                    var image = ws.AddPicture(imagePath3);
                    image.MoveTo(ws.Cell(3, 3).Address);
                    image.Scale(.5);
                }

                ws_src.Delete();

                wb.Save();
            }

wb.Save() を実行すると例外が発生します。imageの処理をコメントアウトするとエラーは発生しません。

結論として、Worksheetを割り当てるusing句を外したところ、正常に動作するようになりました。エラー調査の際にOpenXMLのコードもちらっと見たのですが、おそらく画像を追加する際にいったんWorksheetの情報を更新して再割り当てするような処理が必要となります。usingを使っていると再割り当てができないのでエラーになったのではないかと。

ただ、エラー箇所がusing句の中ではなく、Saveを実行した場所というのはよくわからないのですが… 再割り当てできない状態で内部変数をいろいろいじくって、それをファイルに保存する際にそれが検知されてエラーとなる、とかではないかと。

ClosedXMLのサンプルコードを見ていると、Workbookにusing句を使用するものはあるが、Worksheetに使用するものはほとんどない。WorkbookのDisposeで配下のすべてのリソースが解放されるので不要なのだろう。上記書き方が一般的ではないのかも。