スポンサー広告 - スポンサーサイト

--/--/-- (--) --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【プログラミング】JAVA - POI備忘録 其の壱

2010/11/27 (土) 17:46

POI 3.7でのお話。
ちょっと弄る機会があったので。

セルに対する背景色とか、枠線とか、所謂「スタイル」について。
セルそれぞれが設定値を持つものだと思いきや、
なんとスタイルはブックが持つものでした。
で、セルはどのスタイルが設定されているかの参照情報を持つという仕組み。

なので、同じスタイルが設定されているセルが複数存在する場合は、
その中のとあるセルのスタイルを変更すると、該当するすべてのセルに影響を及ぼす。
で、このスタイルは1つのブックに最大4000個までが上限となっている。

これはPOIの仕様というわけではなく、そもそものエクセルの仕様であるので、
POIはその仕様通りの動きをしているだけなのでした。
全然知らなかったぜぇ。エクセルめぇ。

すっかり騙されてしまったので、記録しておく。

例えば、以下の自前のメソッドは上記の問題を孕む。
/**
* 指定範囲のセル全てに指定の背景色を設定する
* @param sheet 操作対象のシート
* @param coordinate 操作対象の座標範囲(例 AW18:BG28)
* @param color 背景色
*/
public void setBackgroundColor(Sheet sheet, String coordinate, short color) {

CellRangeAddress address = CellRangeAddress.valueOf(coordinate);
int firstRow = address.getFirstRow();
int lastRow = address.getLastRow();
int firstColumn = address.getFirstColumn();
int lastColumn = address.getLastColumn();

for (int i = firstRow; i <= lastRow; i++) {
for (int j = firstColumn; j <= lastColumn; j++) {
Row row = CellUtil.getRow(i, sheet);
Cell cell = CellUtil.getCell(row, j);

CellStyle style = cell.getCellStyle();
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFillBackgroundColor(color);

cell.setCellStyle(style);
}
}
}
操作対象のセルからスタイルを取り出して更新しているって処理。
エクセルの仕様を理解していないとこれで問題無いように思えるが、
同じスタイルを参照しているセル全てに影響を及ぼすので、
場合によっては全てのセルの見た目が変わってしまう可能性がある。(むしろあった!)

そこで便利なメソッドを見つけた。
CellUtil.setCellStyleProperty である。
これを使って以下のように変更する。
/**
* 指定範囲のセル全てに指定の背景色を設定する
* @param sheet 操作対象のシート
* @param coordinate 操作対象の座標範囲(例 AW18:BG28)
* @param color 背景色
*/
public void setBackgroundColor(Sheet sheet, String coordinate, short color) {

CellRangeAddress address = CellRangeAddress.valueOf(coordinate);
int firstRow = address.getFirstRow();
int lastRow = address.getLastRow();
int firstColumn = address.getFirstColumn();
int lastColumn = address.getLastColumn();

for (int i = firstRow; i <= lastRow; i++) {
for (int j = firstColumn; j <= lastColumn; j++) {
Row row = CellUtil.getRow(i, sheet);
Cell cell = CellUtil.getCell(row, j);
CellUtil.setCellStyleProperty(cell, sheet.getWorkbook(), CellUtil.FILL_PATTERN, CellStyle.SOLID_FOREGROUND);
CellUtil.setCellStyleProperty(cell, sheet.getWorkbook(), CellUtil.FILL_FOREGROUND_COLOR, color);
}
}
}
CellUtil.setCellStyleProperty が何をやっているかというと、
変更後のスタイルと同様の設定内容のスタイルが既にブックに存在しないかをチェックし、(最大で4000ループってことになるか)
存在していればそれを使う。
無ければ新たにスタイルを作成し、それを使う。
さらに、元々のスタイルに設定を追加する処理になっているので、
例えば上記のメソッドの場合だと、元々枠線が設定されていたセルが対象の場合、
枠線の設定は残しつつ背景が追加される。要するに追記できるって感じ。
嗚呼…便利だね♪

CellUtil は結構興味深いので、どんなメソッドが用意されているのかチェックしておくことをお勧めする。
関連記事

コメントの投稿

非公開コメント

検索フォーム
RSSリンクの表示
カレンダー
06 | 2017/07 | 08
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
月別アーカイブ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。