poi读取Excel文件报异常

走海角 2012-03-07 03:07:37
最近使用poi操作Excel时,在读取Excel到文件到文件流中时,抛出一下异常:
org.apache.poi.hssf.record.RecordFormatException: String record was supplied but formula record flag is not set
at org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate.<init>(FormulaRecordAggregate.java:51)
at org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate.construct(ValueRecordsAggregate.java:159)
at org.apache.poi.hssf.record.aggregates.RowRecordsAggregate.<init>(RowRecordsAggregate.java:89)
at org.apache.poi.hssf.model.Sheet.createSheet(Sheet.java:219)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:281)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:196)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:313)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:294)
at com.nec.nes.eks.importEmployeeAttendance.service.ImportEmployeeAttendanceService.getEmployeeAttendanceFromXls(ImportEmployeeAttendanceService.java:164)
at com.nec.nes.eks.importEmployeeAttendance.action.ImportEmployeeAttendanceAction.uploadAnalyzeFile(ImportEmployeeAttendanceAction.java:167)
at com.nec.nes.eks.importEmployeeAttendance.action.ImportEmployeeAttendanceAction.exe(ImportEmployeeAttendanceAction.java:86)
at com.nec.nes.comn.core.action.BaseAction.execute(BaseAction.java:79)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at com.nec.nes.comn.core.servlet.OurActionServlet.service(OurActionServlet.java:96)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Unknown Source)
--------------------------------------------------------------------------------------------------------------
在网上搜了很长时间,没有找到正确答案,通过自己实践,找出原因。
在用poi读取Excel时,应保证Excel文件默认选中的是第一个sheet页,即异常中的提示:String record was supplied but formula record flag is not set
...全文
272 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
LucEaspe 2012-03-07
  • 打赏
  • 举报
回复

// 最近写的。你参考下,不理解再问
package se.analyzer.parser.impl;

import java.io.File;
import java.io.FileInputStream;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import se.analyzer.parser.Parsable;
import se.analyzer.parser.Parser;

public class ExcelParser extends Parser implements Parsable {

@Override
public String getContext(File arg) {
StringBuffer context = new StringBuffer();
try {
// 创建对Excel工作簿文件的引用
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(arg));
// 获取sheet数
int iSheetNum = workbook.getNumberOfSheets();
for (int numSheets = 0; numSheets < iSheetNum; numSheets++) {
if (null != workbook.getSheetAt(numSheets)) {
// 获得一个sheet
HSSFSheet aSheet = workbook.getSheetAt(numSheets);
int iRowNum = aSheet.getLastRowNum();
for (int rowNumOfSheet = 0; rowNumOfSheet <= iRowNum; rowNumOfSheet++) {
if (null != aSheet.getRow(rowNumOfSheet)) {
HSSFRow aRow = aSheet.getRow(rowNumOfSheet);

int iCellNum = aRow.getLastCellNum();
for (int cellNumOfRow = 0; cellNumOfRow < iCellNum; cellNumOfRow++) {

if (null != aRow.getCell(cellNumOfRow)) {
HSSFCell aCell = aRow.getCell(cellNumOfRow);

int cellType = aCell.getCellType();
switch (cellType) {
case 0:// Numeric
double sCell = aCell
.getNumericCellValue();
context.append(sCell);
break;
case 1:// String
String strCell2 = aCell
.getStringCellValue();
context.append(strCell2);
break;
default:
// other data
String strCell3 = aCell
.getStringCellValue();
context.append(strCell3);
break;
}
}
context.append(" ");
}
}
context.append("\n");
}
}
context.append("\n");
}

} catch (Exception e) {
e.printStackTrace();
}
return context.toString();
}

}
wula0010 2012-03-07
  • 打赏
  • 举报
回复
找到原因,解决问题了么?
目前处理Excel的开源javaAPI主要有两种,一是Jxl(Java Excel API),Jxl只支持Excel2003以下的版本。另外一种是Apache的Jakarta POI,相比于Jxl,POI对微软办公文档的支持更加强大,但是它使用复杂,上手慢。POI可支持更高的Excel版本2007。对Excel读取POI有两种模式,一是用户模式,这种方式同Jxl的使用很类似,使用简单,都是将文件一次性读到内存,文件小的时候,没有什么问题,当文件大的时候,就会出现OutOfMemory的内存溢出问题。第二种是事件驱动模式,拿Excel2007来说,其内容采用XML的格式来存储,所以处理excel就是解析XML,而目前使用事件驱动模式解析XML的API是SAX(Simple API for XML),这种模型在读取XML文档时,并没有将整个文档读入内存,而是按顺序将整个文档解析完,在解析过程中,会主动产生事件交给程序中相应的处理函数来处理当前内容。因此这种方式对系统资源要求不高,可以处理海量数据。笔者曾经做过测试,这种方法处理一千万条,每条五列的数据花费大约11分钟。可见处理海量数据的文件事件驱动是一个很好的方式。而本文中用到的AbstractExcel2003Reader、AbstractExcel2007Reader对Excel读取都是采用这种POI的事件驱动模式。至于Excel的写操作,对较高版本的Excel2007,POI提供了很好的支持,主要流程是第一步构建工作薄和电子表格对象,第二步在一个流中构建文本文件,第三步使用流中产生的数据替换模板中的电子表格。这种方式也可以处理海量数据文件。AbstractExcel2007Writer就是使用这种方式进行写操作。对于写入较低版本的Excel2003,POI使用了用户模式来处理,就是将整个文档加载进内存,如果数据量大的话就会出现内存溢出的问题,Excel2003Writer就是使用这种方式。据笔者的测试,如果数据量大于3万条,每条8列的话,就会OutOfMemory的错误。Excel2003中每个电子表格的记录数必须在65536以下,否则就会发生异常。目前还没有好的解决方案,建议对于海量数据写入操作,尽量使用Excel2007。

50,545

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧