POIでEXCELに画像を挿入する

2020年9月15日火曜日

Java POI

t f B! P L

POIでEXCELに画像を挿入する

JAVA + Apache POIで、Excelに画像を挿入する方法を、サンプルコード付きで解説します。HSSF(.xls) と、XSSF(.xlsx) の両方に対応出来るコードで作成します。

POIでEXCELに画像を挿入する

サンプルコード

早速、サンプルコードです。コードの詳しい内容は、このサンプルコードの後で解説していますので、詳しく知りたい方は、そちらも参照してください。

Workbook book = new XSSFWorkbook();   //.xlsの場合は、new HSSFWorkbook()
Sheet sheet = book.createSheet();

//画像ファイルをByte配列に変換
InputStream in = new FileInputStream("image.jpg");
byte[] bytes = IOUtils.toByteArray(in);
in.close();

//画像をworkbookに追加
int pictureIdx = book.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);

//Drawingインスタンスを取得
Drawing patriarch = sheet.createDrawingPatriarch();

//ClientAnchorインスタンスを取得
ClientAnchor anchor = book.getCreationHelper().createClientAnchor();

//画像挿入位置・サイズを指定する
anchor.setCol1(1);
anchor.setRow1(1);
anchor.setCol2(6);
anchor.setRow2(6);
//オフセットを指定
anchor.setDx1(Units.EMU_PER_PIXEL * 10);
anchor.setDy1(Units.EMU_PER_PIXEL * 10);
anchor.setDx2(Units.EMU_PER_PIXEL * -10);
anchor.setDy2(Units.EMU_PER_PIXEL * -10);

//画像のアンカータイプを設定
anchor.setAnchorType(ClientAnchor.MOVE_AND_RESIZE);

//指定した表示位置に画像を設定
patriarch.createPicture(anchor, pictureIdx);

スポンサーリンク

表示位置・サイズの指定

画像の表示位置とサイズの指定は、セルの範囲指定で行います。

anchor.setCol1(1);
anchor.setRow1(1);
anchor.setCol2(6);
anchor.setRow2(6);

上のようなコードで画像の挿入位置を指定した場合、次イメージのオレンジで塗りつぶしたエリア(B2~F6の範囲)に、画像が挿入されます。

画像の挿入位置とサイズ指定方法のイメージ

画像挿入範囲の終端(Col2, Row2)の指定には注意が必要

画像挿入範囲の終端(Col2, Row2)の指定には少し注意が必要です。
画像はCol2, Row2で指定したセルの左上の位置まで引き延ばされます。
その為、Col2=6, Row2=6とした場合、上のイメージの通り、セル(5,5)の右下の部分までしか画像が表示されません。

オフセットを指定

画像の余白は、setCol1/setRow1/setCol2/setRow2で指定したセルからの、オフセットで指定します。

下のコードでは、上下左右にそれぞれ10pxずつ余白を入れています。
※ 右と下の余白は、マイナス値で指定する必要があるのが注意です。

anchor.setDx1(Units.EMU_PER_PIXEL * 10);
anchor.setDy1(Units.EMU_PER_PIXEL * 10);
anchor.setDx2(Units.EMU_PER_PIXEL * -10);
anchor.setDy2(Units.EMU_PER_PIXEL * -10);

Dx1/Dy1/Dx2/Dy2で指定した値は、下のイメージのように適用されます。

Dx1/Dy1/Dx2/Dy2の設定イメージ

単位はEMU

setDx1などに指定する値は、EMUという単位で指定する必要があります。
EMUが何の単位か正直よく分かりませんが(^^;)、公式ドキュメントを見ると、1ピクセルは9525 EMU、1ポイントは12700 EMUと定義されているようです。

なので、ピクセル指定でオフセットを指定する場合は、

anchor.setDx1(Units.EMU_PER_PIXEL * 10);

ポイント指定でオフセットを指定する場合は、

anchor.setDx1(Units.EMU_PER_POINT * 1);

のようにします。

アンカータイプ

アンカータイプとは、セル・列・行の移動またはサイズ変更に合わせて、画像を移動およびリサイズするかの指定を行うオプションのことです。

Excelでは、[図の書式設定]のプロパティから指定できるオプションを、POIではJavaのコードから指定できます。

enter image description here

画像のアンカータイプは、次のコードで指定できます。

anchor.setAnchorType(ClientAnchor.MOVE_AND_RESIZE);

アンカータイプの種類

コードで指定できるアンカータイプは、org.apache.poi.ss.usermodel.ClientAnchor.AnchorTypeに定数が定義されており、内容を以下の表にまとめました。

定数 説明
MOVE_AND_RESIZE(0) 行/列をリサイズすると、画像も移動/リサイズを行う。
DONT_MOVE_DO_RESIZE(1) 画像のリサイズのみを行う。
MOVE_DONT_RESIZE(2) 画像の移動のみを行う。
DONT_MOVE_AND_RESIZE(3) 画像のリサイズ/移動共に行わない。

さいごに

Excelに画像を載せる要件があった為、調べてみましたが、以外と簡単に出来る事が分かりました。

今回紹介したサンプルコードは、画像の縦横比について考慮をしていません。画像は、setCol1/setRow1/setCol2/setRow2で指定したセル範囲にピッタリ配置される為、セルの範囲と画像の縦横比が合っていないと、画像の縦横比が崩れた残念な表示になる事があるため、注意が必要です。

基本的には、セルのサイズが分かっている場所に貼りましょう。。。

スポンサーリンク

QooQ