valid,invalid

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

POIで、読み込んだExcelファイルから図形を取得して値をセットする

Excelファイル(※2007以降の.xlsx形式)から目的の図形を取得し、値をセットする。
今回はテキストボックスを取得してセットするサンプル。

既に対象のWorkbookとSheetを取得している状態から。

// 図形描画の為のXSSFDrawingから図形のListを取得
XSSFDrawing drawing = sheet.createDrawingPatriarch();
List shapeList = drawing.getShapes();

// Listから目的の図形を探索
for (XSSFShape sh : shapeList) {
// (1)実際の型を確認
if (sh instanceof XSSFSimpleShape) {
XSSFSimpleShape ss = (XSSFSimpleShape) sh;
// (2)テキストの値をkeyに対象かどうか判断
if (ss.getText().equals("key")) {
ss.setText("value you want to set");
}
}
}


(1)Listで取得されるオブジェクトはXSSFShapeのサブクラス(※)であり、検査せずにSimpleShapeとして扱おうとするとClassCastExceptionが発生する。
 ※こいつら。↓
  XSSFConnector, XSSFGraphicFrame, XSSFPicture, XSSFShapeGroup, XSSFSimpleShape。

(2)APIDocなんかを読み漁ったけれども、定義した名前から図形を取得する方法がわからず。とりあえずテキストから判断するやり方で記述。


【環境】

 POI 3.10
 Java SE7

【参考】

XSSFSimpleShape (POI API Documentation)


[追記 2014/5/7] 

上記のやり方で値をセットすると、図形にもともと設定されていたフォントや揃方がクリアされてデフォルト値になってしまうことがわかった。

もともと設定されていたフォントなどを維持したままテキストのみを置き換える場合は下記のようにテキストを分解し、テキストの最小単位(TextRun)に対して操作を行わなければいけないらしい。

// 上記の11行目から
if (ss.getText().equals("key")) {
for (XSSFTextParagraph p : ss.getTextParagraphs()) {
for (XSSFTextRun r : p.getTextRuns()) {
r.setText("value you want to set"); // ※1
}
}
}

※1 改行を含む文字列をブチ込んでも大丈夫だった。だがParagraphの扱いがよくわかっていないので、複数行を操作する場合はもう少し工夫が必要なのかもしれない。

FontはFontクラスで管理してたり、AlignはTextParagraphで管理していたり。Excelの実装自体がそうなのかもしれないけど、Excel上の設定と各オブジェクトの結びつきがわかりづらく、直感的に操作しづらい。。