2013-10-23 65 views
0

当我尝试打开POI的.xlsx文件打开的工作簿时,我得到一个异常:POI不能打开在Excel

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中也会正确打开。

回答

2

从你说的话,这是你有一个.xlsx文件,但它的转向了在HSSF没有工作簿条目,我要推断,你有一个加密的.xlsx文件

基本上有4处理一个的.xls或.xlsx文件的方式:

  • 未加密的.xls文件 - OLE2存储,可与HSSF
  • 加密.xlsx文件 - OLE2存储,一些记录加密,用HSSF工作,如果你supply the password
  • 未加密的.xlsx文件 - OOXML(zip的xml)存储,与XSSF一起使用
  • 加密的.xlsx文件 - 存储在OLE2中,其中包含OOXML的加密部分,其中.....最终适用于XSSF它是讨厌的)

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

你需要做的是follow the instructions on the POI Encrypted Documents page。基本上,你的代码需要是这样的:

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,所以现在会抛出一个EncryptedDocumentException,如果你给一个加密.xlsx文件到HSSF,这样你就可以制定出更轻松地出错你在哪里

+0

它受到保护,但没有加密。我试过你的代码,并得到一个例外,它无法找到一个算法 – qwerty

+0

在许多情况下,由于Microsoft最知道的原因,protected = encrypted。可以用默认密码保护,但仍然会被加密 – Gagravarr

+0

有趣!那么为什么我会得到一个异常java.security.NoSuchAlgorithmException:无法找到任何支持AES/ECB/NoPadding的提供商 – qwerty