日々常々

ふつうのプログラマがあたりまえにしたいこと。

POIを使ってみる/「表示形式の設定が失われた可能性があります」

POI(3.6)で作成したファイルをExcelで開いた際に「表示形式の設定が失われた可能性があります」というダイアログが表示されました。
直接の原因は、ファイルに定義されている表示形式の数が多すぎることにあるようです。表示形式はHSSFCellStyle#getDataFormatStringで取得でき、これによりセルの書式設定のフォーマットが取得できます。ExcelVBAの NumberFormat が該当すると考えて良いと思います。MicrosoftExcel2003で扱えるセル書式の上限は約4,000という事なのですが、表示形式単独だと300ちょっとくらいで上限なように見えました。
調べたところ、どうも HSSFCellStyle#cloneStyleFrom の実装が原因のようです。Workbook間コピーを行う際に CellStyle#cloneStyleFrom を使用していたわけですが、Workbookの異なるCellStyleに対して行うと、DataFormatとFontのインスタンスを生成し、新たに追加しています。これにより、表示形式が標準のものや定義済みのものも重複して作成されるため、コピーしたCellStyleの数だけDataFormatやFontも作成される事になりました。
これらのDataFormat、FontはWorkbookの持ち物になっていて、createは出来るのですがremoveとかは出来なさそう。となってくると、数が少ないうちは良いのですが、多くなってくると HSSFCellStyle#cloneStyleFrom は使えないという事になってしまいます。