現象
最近javaシステムが作成したExcelを開くとエラーが発生すると報告されました。
「はい」で修復したらファイルが開けますが、修復ログ情報が出てきます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><logFileName>error101160_01.xml</logFileName>
<summary>
ファイル 'C:\Users\mycount\Downloads\XXXXXXX.xlsm' にエラーが検出されました
</summary>
<removedRecords>
<removedRecord>
削除されたレコード: /xl/workbook.xml パーツ内の名前付き範囲 (ブック)
</removedRecord>
</removedRecords>
</recoveryLog>
この現象は、一部のファイルしか発生しません。POIバージョンは5.1.0です。
分析
名称付き範囲
エラー情報には、「名称付き範囲」の言葉は出てきました。その詳細情報は、数式タブの「名称の管理」アイコンで確認できます。
エラー発生するものとエラー発生しないものを比較して、エラー発生する場合、シートに印刷範囲設定と関わる名称付き範囲がなくなっているとわかりました。
正常の場合のシート名は、「C999999」みたいで、頭文字「C」と数字の後続です。異常の場合のシート名は「C999S99」みたいで、途中も英字があります。
プログラムには、印刷エリアを設定するPOI関数の呼び出しがあります。
Sheet sheet = workbook.getSheet(sheetName);
workbook.setPrintArea(workbook.getSheetIndex(sheet), startCol, endCol, startRow, endRow);
シングルコーテーション
Excelのシート名には、禁則文字があるとずっと以前から知っています。
「:」、「\」、「/」、「?」、「*」、「[」、「]」
でも「C999S99」のシート名は別に問題なく設定されているので、禁則文字の問題ではないです。
印刷エリアの設定は、修復により削除されたけれど、手動で設定して正常パターンと比較してみて、シングルコーテーションありと気がつきました。
もし無理やりシングルコーテーションを削除して保存する場合、数式エラーになります。
もしかしてPOIはシングルコーテーションを付けていないからのバグでしょうか。
最新版テスト
POI最新版の5.3.0をダウンロードして試してみて、エラーが解消されます。
原因
新旧POIのソースを比較して以下の違いがあるとわかりました。
シート名にシングルコーテーションを付けるかどうかを判断する関数needsDelimitingに、POI5.3.0にnameStartsWithR1C1CellReferenceの呼び出しを追加されています。
つまりExcel数式に、シート名はもし行とセルの記載に誤認の可能性がある場合、シングルコーテーションを付ける必要です。POI 5.1.0の場合、A1(アルファベット、行番号)形式を対応したが、R1C1(行番号、列番号)形式を対応していません。C999S99の書き方には、「C」の文字はR1C1の識別子になるので、誤認に繋がりました。
おわり
以上、問題解決+原因明確、すっきりになりました!