簡體   English   中英

使用 apache-poi 從 a.ppt 解析 embedded.xlsx 文件時出錯。提供的 POIFSFileSystem 不包含 BIFF8“工作簿”條目

[英]Error when parsing an embedded .xlsx file from a .ppt using apache-poi. The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry

使用 apache poi 從 .ppt 文件中提取 embedded.xlsx 文件時,我遇到了一個問題。 如果有人能幫助我,那就太好了。

問題主題:

試圖解決的問題:提取嵌入在“.ppt”中的“.xlsx”文件。

我目前使用的是 apache-poi。

似乎當我嘗試使用 hslfSlideShow.getEmbeddedObjects() 執行此操作時,我得到了 xlsx object 就好了,但是當我嘗試使用 WorkbookFactory.create(inputStream) 將其轉換為 XLSFWorkbook object 時,它拋出了一個錯誤提示

java.lang.IllegalArgumentException: The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. Is it really an excel file? Had: [OlePres000, Ole, CompObj, Package]
at org.apache.poi.hssf.usermodel.HSSFWorkbook.getWorkbookDirEntryName(HSSFWorkbook.java:286)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:326)
at org.apache.poi.hssf.usermodel.HSSFWorkbookFactory.createWorkbook(HSSFWorkbookFactory.java:64)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:167)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:112)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:253)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:221)

有趣的是,即使它是一個 xlsx 文件,它也會調用 HSSFWorkbookFactory。

而且沒有 xlsx 文件沒有損壞/密碼保護 我可以打開它。

此外,如果我嘗試解析the.xlsx文件而不將其嵌入到 the.ppt 中,它也能正常工作。

當我將其嵌入 .pptx 文件並調用諸如 xmlSlideShow.getAllEmbeddedParts() 之類的方法以從 .pptx 獲取嵌入對象時,解析工作正常。

促進對答案的一些評論和調查......

這是舊版本 Apache POI 的一個限制,但在 7 月份的 r1880164 中得到修復。

出於向后兼容的原因,PowerPoint 經常(但不總是...)編寫嵌入的 OOXML 資源,這些資源包裝在中間 OLE2 層中。 這樣做的好處是,希望嵌入式辦公文檔能夠處理類似xls / doc的工具/程序,但要以另一層包裝為代價。

較新版本的 Apache POI(5.0 應該是第一個已修復的版本)在WorkbookFactory中支持接收這樣的 OLE2 包裝器,提取底層xlsx stream 並將其交給XSSFWorkbook (舊版本對基於 OLE2 的受密碼保護的xlsx文件執行此操作,但對未加密的同類文件執行此操作)

現在,如果您停留在受影響的 POI 版本上,您需要的代碼是這樣的(主要取自單元測試驗證支持:):

POIFSFileSystem fs = new POIFSFileSystem(data.getInputStream());
if(fs.getRoot().hasEntry("Package")) {
     DocumentInputStream dis = new DocumentInputStream((DocumentEntry)fs.getRoot().getEntry("Package"));
     try (OPCPackage pkg = OPCPackage.open(dis)) {
            XSSFWorkbook wb = new XSSFWorkbook(pkg);
            handleWorkbook(wb);
            wb.close();
     }
} else {
     try (HSSFWorkbook wb = new HSSFWorkbook(fs)) {
            handleWorkbook(wb);
     }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM