POI无法打开在Excel中打开的工作簿

当我尝试在POI中打开一个.xlsx文件时,出现exception:

java.lang.IllegalArgumentException: The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. Is it really an excel file? at org.apache.poi.hssf.usermodel.HSSFWorkbook.getWorkbookDirEntryName(HSSFWorkbook.java:223) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:245) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:188) 

我注意到代码正在考虑它.xls文件,即使名称是.xlsx,我正在使用WorkbookFactory.create(fileInputStream); 打开文件。

我尝试将文件重命名为.zip,并在WinZip中打开,我得到一个错误 – 无效的zip文件。

该文件在Excel中打开,如果我保存它(不做一个更改),然后它在POI中正确打开。

从你说什么,这是你有一个.xlsx文件,但它在HSSF中没有工作簿条目,我会推断你有一个encryption的.xlsx文件

基本上有4种处理.xls或.xlsx文件的方法:

  • 未encryption的.xls文件 – OLE2存储,与HSSF一起使用
  • encryption的.xlsx文件 – OLE2存储,某些loggingencryption,如果提供密码 ,则与HSSF一起使用
  • 未encryption的.xlsx文件 – OOXML(zip的xml)存储,适用于XSSF
  • encryption的.xlsx文件 – 存储在OLE2,其中包含encryption的部分,其中包装OOXML,这…..最终与XSSF(这是讨厌的)

所以,我认为正在发生的是你正在检查文件的types,看到它的OLE2,然后传递给HSSF。 HSSF寻找它的工作,不能看到他们,并放弃

您需要执行的操作是按照“POIencryption文档”页面上的说明进行操作 。 基本上,你的代码需要是这样的:

 EncryptionInfo info = new EncryptionInfo(filesystem); Decryptor d = Decryptor.getInstance(info); try { if (!d.verifyPassword(password)) { throw new RuntimeException("Unable to process: document is encrypted"); } InputStream dataStream = d.getDataStream(filesystem); XSSFWorkbook wb = new XSSFWorkbook(dataStream); // Process XLSX file here } catch (GeneralSecurityException ex) { throw new RuntimeException("Unable to process encrypted document", ex); } 

如果您使用最新版本的POI,那么现在如果您将一个encryption的.xlsx文件提供给HSSF,它现在会抛出EncryptedDocumentException ,所以您可以更轻松地解决出错的地方