Excel の制限で書式は 4000 までしか指定できない
Clojure+docjure を使って 7000 行くらいのデータを Excel に書きだそうとしたら以下の例外が出た。
Exception in thread "main" java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:1120)
調べると POI と言うより Excel のそもそもの制限みたい。
Excel 2003 でまさに 4000 まで、2007 でも拡張されたが 64000 までとか。
http://support.microsoft.com/kb/213904/ja
回避するには CellStyle オブジェクト作って使い回すべしとの事らしい。
そもそもの Excel の制限から言えばまあ妥当な話か。
ただ docjure でも add-row! の中では createCell を呼んでいてそれはいいのだが、
スタイルを使い回す部分が見当たらないし Cell オブジェクト作る時にスタイル挟み込むよう
な関数が見当たらず。
Java/POI にするか docjure を修正になるがどっちもめんどくさ。
[2013/04/20 追記]
これ書き出す時のデータに日付型が含まれているので add-row!(add-rows!) すると
日付型を書き出す時に新たに CellStyle オブジェクトを毎回作ってるのが直接の原因だった。
docjure ソースの該当コード↓
(defn apply-date-format! [cell format] (let [workbook (.. cell getSheet getWorkbook) date-style (.createCellStyle workbook) ; ← ここ format-helper (.getCreationHelper workbook)] (.setDataFormat date-style (.. format-helper createDataFormat (getFormat format))) (.setCellStyle cell date-style)))
こいつは add-row! から呼び出され、add-rows! は add-row! を doseq で回してる実装になっており、結果毎回 CellStyle オブジェクトが作られ、簡単に書式制限 4000 に引っかかってた。多分 4000 行じゃなくて 4000 セル分超えたらエラーになるんじゃなかろうか。
add-row(s)! なり apply-date-format! の定義を書き換えればとも思ったが、読み込んだライブラリの定義を上書きする方法を知らないので、書き出し時は日付型を使わない形で回避。