読者です 読者をやめる 読者になる 読者になる

valid,invalid

関心を持てる事柄について

Apache POIで指定した範囲の中心に画像を貼り付けようとして挫折

Java Excel POI

下記の条件でExcelファイル(※2007以降の.xlsx形式)に画像を貼り付ける。(だいぶ限定的…)

1.画像を貼り付けるセル範囲が指定されている。
2.画像は指定された範囲内で、アスペクト比を保ったまま最大化する。
3.範囲は任意だが、指定された範囲のセルはすべて同じ幅であり、
 かつ指定された範囲のセルはすべて同じ高さとする。



こんな感じ。(水平・垂直方向が逆のケースもあり)


結論から言うと、完全にアスペクト比を保ったままの最適化は出来なかった。

上記図で言うmarginは画像貼り付け先の開始位置をずらしつつ、オフセットを指定することで構成されるが、オフセットの指定はint型でしか行えないことによる。(必要なオフセットは当然、小数の場合もある)

単純なことだが、それに気付くまでの軌跡は↓。。
 
// 画像とセル範囲のアスペクト比を比較
double imgRatio = (orgImgWidth / (double)orgImgHeight);
double cellRangeRatio = (cellRangeWidth / (double)cellRangeHeight);

// 高さを最大化し、水平方向位置を計算する
if (imgRatio < cellRangeRatio) {
// 貼り付けられる画像の幅
double imgWidth = (orgImgWidth * (cellRangeHeight / (double)orgImgHeight));

// 余白の幅
double margin = (cellRangeWidth - imgWidth) / 2 ;
int offsetCol = (int)(margin / cellWidth);
imgStartCol = rcol1 + offsetCol;
imgEndCol = rcol2 - offsetCol;
int offset = (int)(XSSFShape.EMU_PER_PIXEL * (margin % cellWidth));
dx1 = offset;
dx2 = offset;

// 横を最大化し、垂直方向位置を計算する
} else if (imgRatio > cellRangeRatio) {
// 貼り付けられる画像の高さ
double imgHeight = (orgImgHeight * (cellRangeWidth / (double)orgImgWidth));

// 余白の高さ
double margin = (cellRangeHeight - imgHeight) / 2 ;
int offsetRow = (int)(margin / cellWidth);
imgStartRow = rrow1 + offsetRow;
imgEndRow = rrow2 - offsetRow;
int offset = (int)(XSSFShape.EMU_PER_PIXEL * (margin % cellHeight));
dy1 = offset;
dy2 = offset;
}

【環境】

 POI 3.10
 Java SE7