Develop with pleasure!

福岡でCloudとかBlockchainとか。

JExcelAPIでMaximum number of format records exceeded. Using default format.

JExcelApiを使用してExcel帳票を出力してると、途中で、

Maximum number of format records exceeded.  Using default format.

って警告のログが出力され、それ以降セルのフォーマットが適用されない帳票が出力される。

この現象は、WritableCell#setCellFormatメソッドを実行した際にJExcelAPIの内部でjxl.biff.NumFormatRecordsExceptionが発生した場合に起きる。

Excel places a constraint on the number of format records that are allowed. This exception is thrown when that number is exceeded This is a static exception and should be handled internally

jexcelapi_2_3_5 Documentation: Class NumFormatRecordsException

とあるので、どうもExcel自体にフォーマット適用の制限数があり、その制限数を超えた場合にこの例外が投げられて、それ以降のフォーマットは適用されなくなるみたい。ちなみにこの制限数自体は、FormattingRecordsクラスにプライベートな定数maxFormatRecordsIndexで定義されてて、定義は441。

てことで、441個を超えてWritableCell#setCellFormatでフォーマットの適用をしたい場合は、その前で一旦ファイル出力するなりして、再度未適用部分からフォーマット適用を再開するなどしないといけない。
ただ、適用するフォーマット数が多ければ多いほど、ファイルIOが発生する機会も増え、パフォーマンスが劣化する。

なんとかならんもんかと、JExcelAPIの↑の判定をしている箇所をコメントアウトしてビルドし直してみた。jxl.biff.FormattingRecords.javaのaddFormatメソッドの

    if (nextCustomIndexNumber > maxFormatRecordsIndex)
    {
      nextCustomIndexNumber = maxFormatRecordsIndex;
      throw new NumFormatRecordsException();
    }

となってる部分を丸ごとコメントアウト。

試しに実行してみると「Maximum number of format records exceeded.」が発生しなくなり、なんと最後までフォーマットが適用されてるじゃないか!

あれ、Excelの制限があったんじゃないの?

まぁ、どんな副作用があるかまでは突っ込んで見てないので、コメントアウトして使うかどうかは精査が必要かな。