poiでセルにスタイルを作る場合、大抵CreateCellStyleを行います。
が・・・
ちょっとトラップがあります。
#Excelの仕様
知っている方は知っていますが、Excelの仕様として
1Bookで作れるスタイルには上限があります。
最大スタイル数 | 最大行数 | |
---|---|---|
2003 | 4000 | 65,536 |
2007 | 64000 | 1,048,576 |
2010 | 64000 | 1,048,576 |
2016,2013 | 64000 | 1,048,576 |
2003だけ最大スタイル数も行数も違います。
相手がどのバージョンのエクセルで開くかわからない場合上記に注意して作った方がいいかも知れません。
これだけ見るとpoiで作る場合でも
2003だったら、4000を超えるcreateCellStyle()を
2007以上だったら、64000を超えるcreateCellStyle()をしなければいいんだ
と思い勝ちですが、ここに大きな落とし穴があります。
#ループの中で回した場合の挙動 ~XSSF~
では検証してみます。
通常ループの中でcreateCellStyle()をnewする事は少ないと思いますが
独自のキャッシュ機構を入れたり、処理上どうしても入れたいって事がない事もないと思います。
for (int i = 0; i < 100; i++){
CellStyle cs = workbook.createCellStyle();
Cell cell = row.createCell(i);
cs.setBorderLeft(BorderStyle.THIN);
cs.setBorderTop(BorderStyle.THIN);
cs.setBorderRight(BorderStyle.THIN);
cs.setBorderBottom(BorderStyle.THIN);
cell.setCellStyle(cs);
}
はい、まぁ予想通りです。
#ループの中で回した場合の挙動 ~HSSF~
問題はこっちです。HSSFはxls形式に対応している為
古いプロジェクトやxlsx形式だと不都合がある場合に良く使われます。
for (int i = 0; i < 100; i++){
HSSFCellStyle cs = workbook.createCellStyle();
HSSFCell cell = row.createCell(i);
cs.setBorderLeft(BorderStyle.THIN);
cs.setBorderTop(BorderStyle.THIN);
cs.setBorderRight(BorderStyle.THIN);
cs.setBorderBottom(BorderStyle.THIN);
cell.setCellStyle(cs);
}
一見すると、型以外さっきのソースと全く同じで100番目のカラムまで罫線でかこまれそうですが・・
おや・・。?
#結論と対策
タイトル通り、CreateCellStyleはループ内で使用すべきではない。
apache側も打開作として、CellUtilという便利なものを出してくれていますので、こちらを使うのが良さそうです。