2013-10-23 63 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