mengineer's blog

ニッチなネタばかりですが。

C# Excelに画像を貼る

C#からExcel内の関数を呼び出すのは、下記ネタでやっていました。 mengineer.hatenablog.com

今回はExcelでシートに画像を貼って保存する、というネタです。

上記ネタでは、”異なるExcelのバージョンだと動かないので注意!”
なんてことを書きましたが、今回はバージョンに関係無く動くように、
遅延バインディングという方法でExcelを呼び出しました。

遅延バインディングによるExcel呼び出し

遅延バインディングとは何ぞや?、って話は、下記が判りやすかったです。 urashita.com

通常はプロジェクトの参照設定で”Microsoft Excel XX.X Object Library”
(XX.XはExcelのバージョンにより異なる)を追加して呼び出しますが、
遅延バインディングの場合、下記のようにdynamic型で定義しておきます。
(もちろん、参照設定は不要です)

    class Excel
    {
        dynamic excelApp = null;
        dynamic workBooks = null;
        dynamic workBook = null;
        dynamic workSheets = null;
        dynamic workSheet = null;
        dynamic range = null;
        dynamic shape = null;

次に、下記のようにType.GetTypeFromProgID("Excel.Application")で、
インストールされているExcel(もしくは同等ソフト)を取得します。

もしExcelがインストールされていないとnullが戻ります、ちなみに私の環境
WPS OfficeというOffice互換ソフトでも問題無く取得出来ました、
実行環境(Excelのバージョン等)に関係無く使えるのは便利ですね。

Activator.CreateInstance(excelApplication)で、excelAppにインスタンスを定義、
後は通常の参照設定で使うのと同じ流れでExcelを制御出来ます。

Type excelApplication = Type.GetTypeFromProgID("Excel.Application");
excelApp = Activator.CreateInstance(excelApplication);

画像の貼付

ExcelのShapes.AddPictureというメソッドを使います、パラメータは下記参照。

Shapes. AddPicture メソッド (Excel) | Microsoft Docs

下記はシートのセル”A2"の位置に、”test.bmp”を貼る場合の例。

Left,Topが画像ファイルを貼る位置、A2セルの左上に設定しています、
WidthとHeightは画像の幅と高さですが、とりあえず0に設定します。

workSheet.Shapes.AddPictureで画像を貼った後に、
shape.ScaleHeightとshape.ScaleWidthで倍率を100%にすることで、
オリジナルの画像サイズに戻しているわけです。

もちろん画像サイズが判っている場合は、Width,Heightに値を設定しておけば、
shape.ScaleHeightとshape.ScaleWidthの処理は不要です。

要は、事前にわざわざ画像サイズを調べなくても、
ScaleHeightとScaleWidthを使えば簡単に貼れますよ、というのが今回のツボ。

range = workSheet.Range["A2"];

double Left = range.Left;
double Top = range.Top;
double Width = 0;
double Height = 0;

shape = workSheet.Shapes.AddPicture("test.bmp", true, true, Left, Top, Width, Height);

shape.ScaleHeight(1.0, true);
shape.ScaleWidth(1.0, true);

下記は画像を貼って、Excelファイルで保存する一通りの処理を入れたサンプルです、
保存ファイル名と貼付する画像ファイル名は、引数で渡すようにしています。

Excel 画像ファイル貼付

2020/02/28追記 上記処理だと画像がリンクとして貼られる場合が有ること判明、
下記訂正記事を参照して下さい。

mengineer.hatenablog.com