我正在编写一些代码来将Excel文件导入数据库。文件可能很大(数千行),所以我使用的是Event API。 POI版本为3.9
我打开这样的文件: 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)
Google在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文件格式保存的文件时。
要重现此问题,请创建新电子表格,输入任何数据,然后另存为=&gt; Microsoft Excel 5.0 / 95工作簿(* .xls)。
有没有办法用apache POI读取这种格式,还是我必须强制我的用户在上传之前升级他们的工作簿?
答案 0 :(得分:0)
这是一个版本问题:该文件是旧版本。 要确认这一点,请使用新版本的Excel打开文件,修改,保存并重试。
答案 1 :(得分:0)
在您提出问题时,Apache POI没有其他解决方案。好消息是现在有了!
在新版本的Apache POI中,如果您使用其中一个旧文件调用HSSFWorkbook
或WorkbookFactory
,您将获得更有帮助的OldExcelFormatException抛出
如果您想从这些文件中获取一些信息,那么OldExcelExtractor可以从Excel 95(以及更旧版本)等格式中获取文本和数字。
为了支持这一点,还有一些Record
类,所以你可以做一些基于事件的解析来更详细地处理它们。虽然
答案 2 :(得分:0)
更一般而言,从POI角度来看,OpenOffice或LibreOffice可能以比MS Office更好的质量来编写旧的MS Office格式文档。当POI无法将97版本.xls文件读取为HSSFWorkbook时,我就解决了此问题。