[Java]Apache POI でパスワードがかかったExcelを読み込んだ際に発生する例外
Apache POI 3.6-20091214
パスワードがかかっているExcelファイルを読み込んだ際に発生する例外
拡張子 | 読込パスワード | 書込パスワード | 例外クラス |
xls | 有 | 有 | RecordFormatException |
xls | 有 | 無 | EncryptedDocumentException |
xls | 無 | 有 | 例外は発生せず読み込み可能 |
xlsx | 有 | 有 | InvalidOperationException |
xlsx | 有 | 無 | InvalidOperationException |
xlsx | 無 | 有 | 例外は発生せず読み込み可能 |
ワークブック作成時に上記例外が発生したらパスワードがかかっているとみなすようにしたが、EncryptedDocumentException以外については誤検出がありそう。妥当な対応はないのだろうか。
サンプルコード
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelImportTest { public static void main(String[] args) throws FileNotFoundException, IOException { File folder = new File("./resource/"); File[] list = folder.listFiles(); for (File file : list) { String suffix = getSuffix(file); System.err.println("\n" + file.getName()); Workbook workbook ; try{ workbook = openWorkbook(file, suffix); }catch(Exception e){ e.printStackTrace(); continue; } String value = workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue(); System.err.println("value:" + value); } } private static Workbook openWorkbook(File file, String suffix) throws IOException, FileNotFoundException { if("xls".equals(suffix)){ return new HSSFWorkbook(new FileInputStream(file)); } else if("xlsx".equals(suffix)){ return new XSSFWorkbook(new FileInputStream(file)); } return null; } private static String getSuffix(File path) { if (path.isDirectory()) { return null; } String fileName = path.getName(); int lastDotPosition = fileName.lastIndexOf("."); if (lastDotPosition != -1) { return fileName.substring(lastDotPosition + 1); } return null; } }
実行結果
nopass.xls value:hogege nopass.xlsx value:hogege readpass_hoge.xls org.apache.poi.EncryptedDocumentException: Default password is invalid for docId/saltData/saltHash at org.apache.poi.hssf.record.RecordFactoryInputStream$StreamEncryptionInfo.createDecryptingStream(RecordFactoryInputStream.java:101) at org.apache.poi.hssf.record.RecordFactoryInputStream.(RecordFactoryInputStream.java:169) at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:389) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:276) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:201) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:317) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:298) at ExcelImportTest.openWorkbook(ExcelImportTest.java:32) at ExcelImportTest.main(ExcelImportTest.java:20) readpass_hoge.xlsx org.apache.poi.openxml4j.exceptions.InvalidOperationException: Can't open the specified file: 'C:\Users\USER1~1.DEV\AppData\Local\Temp\poifiles\poi-ooxml-1994526719.tmp' at org.apache.poi.openxml4j.opc.ZipPackage. (ZipPackage.java:102) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:199) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:178) at org.apache.poi.util.PackageHelper.open(PackageHelper.java:53) at org.apache.poi.xssf.usermodel.XSSFWorkbook. (XSSFWorkbook.java:176) at ExcelImportTest.openWorkbook(ExcelImportTest.java:35) at ExcelImportTest.main(ExcelImportTest.java:20) readwritepass_hoge.xls org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance at org.apache.poi.hssf.record.RecordFactory$ReflectionRecordCreator.create(RecordFactory.java:64) at org.apache.poi.hssf.record.RecordFactory.createSingleRecord(RecordFactory.java:263) at org.apache.poi.hssf.record.RecordFactoryInputStream.readNextRecord(RecordFactoryInputStream.java:270) at org.apache.poi.hssf.record.RecordFactoryInputStream.nextRecord(RecordFactoryInputStream.java:236) at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:392) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:276) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:201) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:317) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:298) at ExcelImportTest.openWorkbook(ExcelImportTest.java:32) at ExcelImportTest.main(ExcelImportTest.java:20) Caused by: java.lang.IllegalArgumentException: Name is too long: ???PZ???)???S??K?j??x????E1?qe/6???n????d
なお、最新のPOI(poi-3.9-20121203)では以下の通り
拡張子 | 読込パスワード | 書込パスワード | 例外クラス |
xls | 有 | 有 | EncryptedDocumentException |
xls | 有 | 無 | EncryptedDocumentException |
xls | 無 | 有 | 例外は発生せず読み込み可能 |
xlsx | 有 | 有 | POIXMLException |
xlsx | 有 | 無 | POIXMLException |
xlsx | 無 | 有 | 例外は発生せず読み込み可能 |
実行結果
nopass.xls value:hogege nopass.xlsx value:hogege readpass_hoge.xls org.apache.poi.EncryptedDocumentException: Default password is invalid for docId/saltData/saltHash at org.apache.poi.hssf.record.RecordFactoryInputStream$StreamEncryptionInfo.createDecryptingStream(RecordFactoryInputStream.java:116) at org.apache.poi.hssf.record.RecordFactoryInputStream.(RecordFactoryInputStream.java:184) at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:440) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:280) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:243) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:187) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:322) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:303) at ExcelImportTest.openWorkbook(ExcelImportTest.java:32) at ExcelImportTest.main(ExcelImportTest.java:20) readpass_hoge.xlsx org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13] at org.apache.poi.util.PackageHelper.open(PackageHelper.java:41) at org.apache.poi.xssf.usermodel.XSSFWorkbook. (XSSFWorkbook.java:204) at ExcelImportTest.openWorkbook(ExcelImportTest.java:35) at ExcelImportTest.main(ExcelImportTest.java:20) Caused by: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13] at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:178) at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:662) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:269) at org.apache.poi.util.PackageHelper.open(PackageHelper.java:39) ... 3 more readwritepass_hoge.xls org.apache.poi.EncryptedDocumentException: Default password is invalid for docId/saltData/saltHash at org.apache.poi.hssf.record.RecordFactoryInputStream$StreamEncryptionInfo.createDecryptingStream(RecordFactoryInputStream.java:116) at org.apache.poi.hssf.record.RecordFactoryInputStream. (RecordFactoryInputStream.java:184) at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:440) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:280) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:243) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:187) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:322) at org.apache.poi.hssf.usermodel.HSSFWorkbook. (HSSFWorkbook.java:303) at ExcelImportTest.openWorkbook(ExcelImportTest.java:32) at ExcelImportTest.main(ExcelImportTest.java:20) readwritepass_hoge.xlsx org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13] at org.apache.poi.util.PackageHelper.open(PackageHelper.java:41) at org.apache.poi.xssf.usermodel.XSSFWorkbook. (XSSFWorkbook.java:204) at ExcelImportTest.openWorkbook(ExcelImportTest.java:35) at ExcelImportTest.main(ExcelImportTest.java:20) Caused by: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13] at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:178) at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:662) at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:269) at org.apache.poi.util.PackageHelper.open(PackageHelper.java:39) ... 3 more writepass_hoge.xls value:hogege writepass_hoge.xlsx value:hogege