概要
最近ちょっとExcel帳票機能を実装する要件が出たので、最新版の apache POI のフィジビリしてたら、POIが俺の知らない子になってたので少し調べたのでまとめ。
詳細
結論
この動作が気にくわない場合は version 3.11 以前の poi
を使用する。
ないしは、後述する回避実装を行う必要がある。
※流石に最新版から見ると古すぎるし、その間にバグフィックスも多いので、単純に古い方を使えとも言えないので回避実装がオススメ。
回避実装
String path
や File
経由でテンプレートファイルと紐づけて XSSFWorkbook を開いてしまうとダメ。
仕方ないので、テンプレートファイルを自前で開いて、ファイルのバイナリデータだけ拾って InputStream を受け取るコンストラクタ にバイナリストリームを食わせる。
検証用プロジェクト
まぁぶっちゃけ、後述する参考文献に記載した所のが全てなんだけどね。
GitHub - sugaryo/mvn-poi-feasibility: POI ver3.11問題の検証 @Mavenプロジェクト
再現検証用にバージョン違いでの実装をブランチ切って用意しつつ、回避コードを実装した。
feasibility
/v310
問題の事象が発生しない(テンプレートファイルへの書き込みが行われない)のを確認。/v311
問題の事象が発生する(編集操作がテンプレートファイルへ書き込まれてしまう)のを確認。/fix
参考文献を参考にした回避実装を盛り込み、最新版のPOIで有効性を検証したもの。
所感
問題は、これがバグではなく、ある程度意図して実施された「仕様変更」であるらしい、と言う事。
いわゆる「迷惑な破壊的変更」ですね。
どうも、POIはメモリを馬鹿食いするという批判を受けて、消費メモリを減らす為にこうしたらしい、という話を見かけましたが。
そのために SXSSF
形式の一方通行型の実装追加したんじゃないの?
って思いました。
いや、やるにしてもテンプレートファイル直書きはやめてよ、、、一時ファイルにしといてよ、、、。
あと、出来ればそれ、オプションで動作追加にしてこっちでハンドリングさせてよ、、、。
参考文献
有益な情報、超ありがとうございます!!