2013-04-16 107 views
0

我正在編寫一些代碼來將Excel文件導入到數據庫。這些文件可能很大(數千行),所以我使用的是Event API。 POI版本是3.9使用apache POI讀取excel 2003文件 - FileNotFound

我打開這樣的文件: FileInputStream fin = new FileInputStream(file);

//create record listener 
HSSFRecordListener mainListener = new HSSFRecordListener("aaa.xls"); 
// create a new org.apache.poi.poifs.filesystem.Filesystem 
POIFSFileSystem poifs = new POIFSFileSystem(fin); 
// get the Workbook (excel part) stream in a InputStream 
din = poifs.createDocumentInputStream("Workbook"); 

某些文件將引發最後一行拋出FileNotFoundException。 事實上,如果我用7zip打開這些文件,沒有Workbook條目,但是有Book

我試圖通過打開Book條目解決此問題,如果Workbook未找到。

try { 
    din = poifs.createDocumentInputStream("Workbook"); 
} catch (FileNotFoundException e) { 
    try { 
     din = poifs.createDocumentInputStream("Book"); 
    } catch (FileNotFoundException e1) {      
     FileNotFoundException e2 = new FileNotFoundException("Neither Workbook nor Book found in file!");      
     e2.initCause(e1); 
     throw e2; 
    } 
} 

這導致另一個異常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894) 
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) 
root cause 

org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance 
    org.apache.poi.hssf.record.RecordFactory$ReflectionConstructorRecordCreator.create(RecordFactory.java:65) 
    org.apache.poi.hssf.record.RecordFactory.createSingleRecord(RecordFactory.java:301) 
    org.apache.poi.hssf.record.RecordFactoryInputStream$StreamEncryptionInfo.<init>(RecordFactoryInputStream.java:65) 
    org.apache.poi.hssf.record.RecordFactoryInputStream.<init>(RecordFactoryInputStream.java:182) 
    org.apache.poi.hssf.eventusermodel.HSSFEventFactory.genericProcessEvents(HSSFEventFactory.java:139) 
    org.apache.poi.hssf.eventusermodel.HSSFEventFactory.processEvents(HSSFEventFactory.java:106) 
    pl.veracomp.service.SpreadsheetImportService.process(SpreadsheetImportService.java:369) 
    pl.veracomp.controller.uploadController.onSubmit(uploadController.java:57) 
    org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272) 
    org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268) 
    org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) 
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) 
root cause 

org.apache.poi.hssf.record.RecordFormatException: Not enough data (0) to read requested (2) bytes 
    org.apache.poi.hssf.record.RecordInputStream.checkRecordPosition(RecordInputStream.java:216) 
    org.apache.poi.hssf.record.RecordInputStream.readShort(RecordInputStream.java:233) 
    org.apache.poi.hssf.record.InterfaceHdrRecord.<init>(InterfaceHdrRecord.java:43) 
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    org.apache.poi.hssf.record.RecordFactory$ReflectionConstructorRecordCreator.create(RecordFactory.java:57) 
    org.apache.poi.hssf.record.RecordFactory.createSingleRecord(RecordFactory.java:301) 
    org.apache.poi.hssf.record.RecordFactoryInputStream$StreamEncryptionInfo.<init>(RecordFactoryInputStream.java:65) 
    org.apache.poi.hssf.record.RecordFactoryInputStream.<init>(RecordFactoryInputStream.java:182) 
    org.apache.poi.hssf.eventusermodel.HSSFEventFactory.genericProcessEvents(HSSFEventFactory.java:139) 
    org.apache.poi.hssf.eventusermodel.HSSFEventFactory.processEvents(HSSFEventFactory.java:106) 
    pl.veracomp.service.SpreadsheetImportService.process(SpreadsheetImportService.java:369) 
    pl.veracomp.controller.uploadController.onSubmit(uploadController.java:57) 
    org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272) 
    org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268) 
    org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) 
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) 

谷歌有一些信息關於在POI 3.2和3.7這有事情做與例外Not enough data (0) to read requested (2) bytes固定錯誤,但它似乎是什麼其他。

同樣的文件可以成功地在Excel 2007中當我手動保存他們Save As=>Excel 97/2003打開,7zip的表明Book項已被替換Workbook,我可以成功地與Apache POI導入。

有沒有人發現這個問題?如何解決它?

編輯

問題是,當我嘗試打開保存在Microsoft Excel 5.0/95文件格式的文件。

若要重現此問題,請創建新電子表格,輸入任何數據,並另存爲=> Microsoft Excel 5.0/95工作簿(* .xls)。

有什麼辦法可以用apache POI來讀取這種格式,或者我必須強制用戶在上傳之前升級他們的工作簿嗎?

+0

該文件來自哪裏?'沒有足夠的數據(0)來讀取請求的(2)字節錯誤似乎表明它是一箇舊的或非標準的文件... – Gagravarr

+0

這些文件是內部價格表,與PHP生成Pear_Excel_Spreadseet_Writer,然後打開我們的產品經理,修改等,並保存。 – SWilk

+0

好的,我知道它是什麼... Spreadsheet_Excel_Writer是一個非常古老的庫。它會生成如此之舊的文件格式,以至於7zip甚至無法打開它來顯示結構。但是,當打開Office並保存格式「更新」爲「Microsoft Excel 5.0/95」時。 – SWilk

回答

0

在您提出問題時,Apache POI沒有其他解決方案。好消息是現在有!

在Apache的POI的新版本,如果你調用HSSFWorkbookWorkbookFactory與這些舊文件中的一個,你會得到更多的幫助OldExcelFormatException拋出

如果你想獲得一些信息,這些文件,然後OldExcelExtractor能夠從包括Excel 95(和更老!)的格式中獲取文本和數字。

爲了支持這些,還有一些Record這些類,所以你可以做一些基於事件的解析來更詳細地處理它們。雖然沒有友好的UserModel支持,但

+0

這是一個好消息。我將您的答案標記爲已接受,但我不會嘗試實施它,因爲我們已將基於Excel的解決方案遷移到xlsx文件,因此不再需要。 – SWilk

0

這是一個版本問題:該文件是舊版本。 要確認這一點,請使用新版本的Excel打開文件,對其進行修改,保存並重試。

+0

謝謝你的回答,儘管我已經知道了。問題是如果有什麼方法可以打開舊格式。但我結束扔信息在導入之前手動轉換文件。 – SWilk