スキップしてメイン コンテンツに移動

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で指定したセル範囲にピッタリ配置される為、セルの範囲と画像の縦横比が合っていないと、画像の縦横比が崩れた残念な表示になる事があるため、注意が必要です。

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

スポンサーリンク
スポンサーリンク
スポンサーリンク

コメント

このブログの人気の投稿

axiosの使い方まとめ (GET/POST/例外処理)

axiosの使い方まとめ (GET/POST/例外処理)最近何かとよく使うJavaScriptでAJAX通信を行うaxiosについて、簡単に使い方をまとめました。GETリクエストをaxiosで送るまずはGETリクエストをaxiosで送る方法です。const res =await axios.get('/users') console.log(res.data)分割代入の記法を使うと、以下のようにも書けますconst{data}=await axios.get('/users') console.log(data)クエリパラメータ (URLパラメータ)を指定クエリパラメータを指定する方法は2つあります。1つ目は、axios.getに指定するURLに直接記述する方法です。axios.get('/user?id=123')2つめは、axios.getの第2引数に、オプション指定する方法です。axios.get('/user',{ params:{ id:123}})POSTリクエストをaxiosで送る次はPOSTリクエストをaxiosで送る方法です。JSON形式でPOSTするJSON形式でPOSTする場合は、axios.postの第2引数に、送信するデータをJavaScriptオブジェクトで指定します。const res =await axios.post('/user',{ id:123, name:'Yamada Tarou'})application/x-www-form-urlencoded形式でPOSTするapplication/x-www-form-urlencoded形式でPOSTする場合は、URLSearchParamsを使います。var params =newURLSearchParams() params.append('id',123) params.append('name','Yamada Tarou')const res =await axios.post('/user', params)axios でファイルをアップロードする画像などのファイルを、axiosでアッ…

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決する

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決するタイトルの通りですが、Windows 8 以降では Windows Form アプリケーションで、コントロールの ImeMode に Katakana や KatakanaHalf を設定しても、カタカナになってくれません。なぜ ImeMode が効かないのか?Windows 8 以降、IME Mode の切り替えは、ユーザー単位で切り替わるようになった為、アプリから IME Mode 制御が出来ないようになりました。
(IME をON にした場合、常に ひらがな モードになます)※ Windows 7までは、IME Modeの切り替えはアプリ単位で行われていた為、問題なくアプリから IME制御が行えました。対処方法Windows 8 以降、IMEの制御は、InputScope クラスの利用が推奨されています。
しかし、InputScope クラスは、WPF、Windows ストアアプリでしか使えない為、Windows Formアプリでは使用できません。
(Windows Form はもう使うな!という事でしょうか (涙) )結論としては、コントールパネルの設定で、IMEの制御をユーザ単位から アプリ単位に変更する事ができます。
これで、Windows Formアプリでも 従来通りIMEの制御を行う事が出来ます。おわりにこの方法だと、アプリをインストールする端末すべてに設定が必要となり、とっても面倒です。。。
しかし、今の所これしか方法がない状態です。
これからは Windows Formではなく、WPFや Windows ストアアプリで作れという事ですかね (^^;)

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]MailKitを使ってメールを送るサンプルコードです。(C#)UTF8/iso-2022-jpのエンコーディング指定、GMail/YahooのSMTPサーバで送るなど、4つのサンプルコードでMailKitの使い方を紹介します。MailKitって何?2017年に.NET標準のSystem.Net.Mail.SmtpClientが廃止予定となり、Microsoftより今後はオープンソースライブラリである、MailKitに置き換えるとアナウンスがありました。既にSmtpClientは非推奨になっており、今後は廃止されていきます。現在、SmtpClientを使用したソースコードには、Visual StudioからMailKitを使うよう警告が出るようになっています。さっそく、MailKitを使ってメールを送信するサンプルコードを作っていきます。UTF8でメールを送信文字エンコーディングを、UTF8でメールを送信するサンプルコードです。
MailKitは、デフォルトの文字エンコーディングがUTF8なっている為、シンプルなコードでメールを送信する事ができます。var host ="<smtp server name>"; var port =25;// or 587using(var smtp =new MailKit.Net.Smtp.SmtpClient()){//SMTPサーバに接続する smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto);//認証が必要な場合は、以下のコメントを解除//smtp.Authenticate("<id>", "<password>");//送信するメールを作成する var mail =new MimeKit.MimeMessage(); var builder =new MimeKit.BodyBuilder(); mail.From.Add(new MimeKit.MailboxAddress("",&quo…