実行環境
Javaバージョン:21
POIバージョン:4.1.2
事象
概要
POI3系では正常に動作していたshiftRows()が、POI4系にバージョンを上げたところ、IllegalStateExceptionが発生した。
実行プログラム
以下は実際に動いていたプログラムを簡略化したものです。
シートの4行目から5行目に行をシフトするプログラムになります。
//読み込みファイルパス
String inputPath = "C:\\Users\\inputFile.xlsx";
//初期化
FileInputStream inputFile = null;
Workbook workbook = null;
//ファイルの読み込み
inputFile = new FileInputStream(inputPath);
workbook = new XSSFWorkbook(inputFile);
//シートの読み込み
Sheet sheet = workbook.getSheetAt(0);
//シートの4行目を5行目にシフト
sheet.shiftRows(3, 3, 1);
System.out.println("行の挿入完了");
//リソースのクローズ
workbook.close();
inputFile.close();
プログラムに問題ないように見えますが、実行すると以下の例外メッセージ「IllegalStateException」が出力されます。
Exception in thread "main" java.lang.IllegalStateException: Cannot add merged region A5:C5 to sheet because it overlaps with an existing merged region (B5:E5).
at org.apache.poi.xssf.usermodel.XSSFSheet.validateMergedRegions(XSSFSheet.java:486)
at org.apache.poi.xssf.usermodel.XSSFSheet.addMergedRegion(XSSFSheet.java:413)
at org.apache.poi.xssf.usermodel.XSSFSheet.addMergedRegion(XSSFSheet.java:367)
at org.apache.poi.ss.usermodel.helpers.RowShifter.shiftMergedRegions(RowShifter.java:93)
at org.apache.poi.xssf.usermodel.XSSFSheet.shiftRows(XSSFSheet.java:3030)
at org.apache.poi.xssf.usermodel.XSSFSheet.shiftRows(XSSFSheet.java:2999)
at samplePOI.SamplePOI005.main(SamplePOI005.java:27)
実行対象ファイル(inputFile.xlsx)の確認
ファイルの中身は、一部内容を簡略化したものです。
4行目は「A4:C4」をセル結合しています。
5行目は「B5:E5」をセル結合しています。
原因
結論
POI4系のバグです。
プログラムにミスではないため、同じようなバグに遭遇している方は安心して下さい。
詳細
例外メッセージを確認すると、「MergedRegion」が何行も記述されています。
MergedRegionは、セル結合や解除をする際に使用するメソッドになります。
今回、このセル結合関連の処理が正常に動作していないため、例外が発生しています。
例外メッセージを再度確認します。
Exception in thread "main" java.lang.IllegalStateException: Cannot add merged region A5:C5 to sheet because it overlaps with an existing merged region (B5:E5).
上記のメッセージを簡単に要約すると、
「A5:C5は既にセル結合されているため、B5:E5のセル結合ができません」
と言っているわけです。
つまり、原因は「A5:C5」のセル結合が解除されていないため、例外が発生しています。
更に詳細に原因を調査したところ、本事象は以下の2条件で発生していることがわかりました。
- シフト元とシフト先でセル結合が一部でも重複している
今回の場合、「B4:C4」と「B5:C5」のセル結合が重複している
- シフト先の先頭列のみセル結合が解除される。
以下の状態で、4行目から5行目に行をシフトするプログラムを実行した場合、shiftRowsは実行されるが、シフト先にシフト前のセル結合が残る
実行前
実行後
対処法
対処法は、シフト前にシフト先のセル結合を解除する操作を入れることで、本事象を回避することができます。
大変手間ですが、POI自体を修正することはできないので、この方法以外の回避方法はありません。
POIは、行の挿入をshiftRowsを使って実行しているため、早く治してほしい所です。
他に対応方法やshiftRowsが修正されたなどの情報がありましたら、是非コメントで教えて下さい!
頼むから早く治して下さい!!
コメント