java poi 读取Excel2007版本时内存溢出

柏澄君 2013-01-23 04:57:28
java poi 读取Excel2007版本时内存溢出,Excel有35000行数据,主要是想导入数据库,导入同样大小的Excel2003时没问题,读取Excel2007版本时就内存溢出了。下面是读取Excel2007的代码。哪位大神帮忙看一下啊?

public void readExcel2007(DBModel dbConn, String filePath, String tableName)
throws Exception {
try {

InputStream inp = new FileInputStream(filePath);
XSSFWorkbook wb = new XSSFWorkbook(inp);
int num_sheet = wb.getNumberOfSheets();
for (int i = 0; i < num_sheet; i++) {
XSSFSheet sheet = wb.getSheetAt(i);

int rows = sheet.getPhysicalNumberOfRows(); // 获得行数
if (rows > 0 && rows < 35000) {

sheet.getMargin(XSSFSheet.TopMargin);
for (int r = 0; r < rows; r++) { // 行循环
// 迭代行
XSSFRow row = sheet.getRow(r);
if (row != null && r != 0 && r != 1 && r != 2) {// 不取第一行,第二行
int cells = row.getLastCellNum();// 获得列数
// 迭代单元格
Vector datas = new Vector();//定义存放返还的集合的实体
//ArrayList datas = new ArrayList();
for (short c = 0; c < cells; c++) { // 列循环

// 定义集合datas用于存Excel中一个行的数据
XSSFCell cell = row.getCell(c);
if(cell != null){
String value = getValue2007(cell).toString();//得到每一列的值不管是什么类型都转换成字符串
// 行和列是基于0索引
System.out.println("第" + r + "行 " + "第" + c
+ "列:" + value);
datas.add(value);
}
}
// 向表中插入数据
DBFactory.insertData(dbConn, tableName, datas);
}
//关闭数据库
//DBFactory.closeConnection(dbConn, null);
}
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("readExcel2007 方法异常:" + e);
throw e;
}
}
...全文
8087 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiangrong_lu 2014-09-04
  • 打赏
  • 举报
回复
遇到这个问题了,想问,解决了没?
刨坑数据 2014-07-22
  • 打赏
  • 举报
回复
代码看起来没有什么大问题,需要更细致的debug才能发现问题。建议换换解题思路,例如:每次导入5000行,存入数据库之后再导入5000行直到导完为止。这样的好处是,即使文件再大一些也不会内存溢出。但是,会增加很多代码。
如果想减少代码量,降低开发难度的话,可以考虑用集算器来编写这个分段导入excel文件的程序。因为集算器封装了很多结构化数据的类库,而且代码比较敏捷,因此,代码量可以减少很多。集算器调试也比较直观方便,可以看到每一步的中间结果。
柏澄君 2013-01-25
  • 打赏
  • 举报
回复
我想问一下SXSSFWorkbook的那个构造函数是怎么写的,把xssf传给sxssf。
搞什么哦 2013-01-24
  • 打赏
  • 举报
回复
引用 10 楼 xodbc 的回复:
1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。……
SXSSFWorkbook只支持写操作,用来实现excel导出倒是可以。
为啥呢 2013-01-24
  • 打赏
  • 举报
回复
引用 16 楼 uyerp 的回复:
引用 15 楼 xodbc 的回复:引用 14 楼 uyerp 的回复:引用 10 楼 xodbc 的回复:1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。…… SXSSFWorkbook只支持写操作,用来实现excel导出倒是可以。 sxssf可以以xssf构建,而xssf可以以inputStream构建,这不就是一个读入的缓存流么?……
和我说的有冲突么?
搞什么哦 2013-01-24
  • 打赏
  • 举报
回复
引用 15 楼 xodbc 的回复:
引用 14 楼 uyerp 的回复:引用 10 楼 xodbc 的回复:1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。…… SXSSFWorkbook只支持写操作,用来实现excel导出倒是可以。 sxssf可以以xssf构建,而xssf可以以inputStream构建,这不就是一个读入的缓存流么?不过这与LZ需求无冲突,LZ是不能将……
* When a new node is created via createRow() and the total number * of unflushed records would exceed the specified value, then the * row with the lowest index value is flushed and cannot be accessed * via getRow() anymore. 超过指定内存条数的部分将会被刷入临时文件,并且不能通过getRow()取到。 默认在内存保存100条数据
为啥呢 2013-01-24
  • 打赏
  • 举报
回复
引用 14 楼 uyerp 的回复:
引用 10 楼 xodbc 的回复:1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。…… SXSSFWorkbook只支持写操作,用来实现excel导出倒是可以。
sxssf可以以xssf构建,而xssf可以以inputStream构建,这不就是一个读入的缓存流么?不过这与LZ需求无冲突,LZ是不能将全部的数据源文件和读取出的全部数据同时放进内存,只要解决一个,那就可以解决问题了。
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 12 楼 xodbc 的回复:
引用 11 楼 MMUZHI 的回复:引用 10 楼 xodbc 的回复:1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。 2、将Excel读入数据库时需要将读取行数做个缓存,比如读1000行就写一次数据库,而且写入数据库这个操作可以和下一批次读取EXCEL同时进行,新开个线程去做数据库写入工作。
我再看看,先试试。
为啥呢 2013-01-23
  • 打赏
  • 举报
回复
引用 11 楼 MMUZHI 的回复:
引用 10 楼 xodbc 的回复:1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。 2、将Excel读入数据库时需要将读取行数做个缓存,比如读1000行就写一次数据库,而且写入数据库这个操作可以和下一批次读取EXCEL同时进行,新开个线程去做数据库写入工作。 我感觉你这个靠谱,有没有具体实现方法啊
在你的代码上把数据库操作放进第二层(行)循环再加个计数的int就可以了阿,这个int随行数累加,到1000就插入数据库并datas.clear(),然后将计数清0,最后循环全部结束时如果!datas.isEmpty()就再插一次。 以上就可以解决你的问题,SXSSFWorkbook这个是用来降低读取时的压力的,并发读取和写库是用来优化速度的。
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 10 楼 xodbc 的回复:
1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。 2、将Excel读入数据库时需要将读取行数做个缓存,比如读1000行就写一次数据库,而且写入数据库这个操作可以和下一批次读取EXCEL同时进行,新开个线程去做数据库写入工作。
我感觉你这个靠谱,有没有具体实现方法啊
为啥呢 2013-01-23
  • 打赏
  • 举报
回复
1、SXSSFWorkbook,前面+个S代表流实现,在构造时可以指定缓存行数。 2、将Excel读入数据库时需要将读取行数做个缓存,比如读1000行就写一次数据库,而且写入数据库这个操作可以和下一批次读取EXCEL同时进行,新开个线程去做数据库写入工作。
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 8 楼 wapigzhu 的回复:
可以啊,有什么不行的。。我们公司就这么搞的,你在给他的启动文件里面加-Xmx1G就行了 比如以前启动是java main 改成java -Xmx1G main就行了
具体怎么办啊
wapigzhu 2013-01-23
  • 打赏
  • 举报
回复
可以啊,有什么不行的。。我们公司就这么搞的,你在给他的启动文件里面加-Xmx1G就行了 比如以前启动是java main 改成java -Xmx1G main就行了
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 6 楼 wapigzhu 的回复:
引用 楼主 MMUZHI 的回复:本帖最后由 MMUZHI 于 2013-01-23 17:09:54 编辑 java poi 读取Excel2007版本时内存溢出,Excel有35000行数据,主要是想导入数据库,导入同样大小的Excel2003时没问题,读取Excel2007版本时就内存溢出了。下面是读取Excel2007的代码。哪位大神……
是调虚拟机的内存么 具体怎么执行啊 交给客户 不能这么办吧
wapigzhu 2013-01-23
  • 打赏
  • 举报
回复
引用 楼主 MMUZHI 的回复:
本帖最后由 MMUZHI 于 2013-01-23 17:09:54 编辑 java poi 读取Excel2007版本时内存溢出,Excel有35000行数据,主要是想导入数据库,导入同样大小的Excel2003时没问题,读取Excel2007版本时就内存溢出了。下面是读取Excel2007的代码。哪位大神帮忙看一下啊? pub……
这种如果不是设计上的缺陷造成的OOM, 如果没有一段一段读的方法 直接设置-Xmx1G就行了吧,不够就继续扩..
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 4 楼 suciver 的回复:
是list集合太大了溢出还是excel已加载进来就溢出了?
我用的Vector,一运行就溢出,感觉是已加载进来就溢出了,XSSFWorkbook好像是一开始都加载进来的
suciver 2013-01-23
  • 打赏
  • 举报
回复
是list集合太大了溢出还是excel已加载进来就溢出了?
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
引用 1 楼 suciver 的回复:
是哪里溢出的是List集合的溢出还是加入excel文件的溢出
读取1000行左右的时候正常,度三万行时就溢出了
柏澄君 2013-01-23
  • 打赏
  • 举报
回复
这是异常的信息 应该是读取excel文件的溢出 Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3039) at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3060) at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3250) at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java:1082) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1802) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseTagNS(PiccoloLexer.java:1362) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXMLNS(PiccoloLexer.java:1293) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXML(PiccoloLexer.java:1261) at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:4808) at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290) at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400) at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714) at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3439) at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1270) at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1257) at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345) at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source) at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:138) at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:130) at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:286) at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:159) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:186) at cn.com.jcda.poiput2database.ReadExcelToDBTool.readExcel2007(ReadExcelToDBTool.java:45) at cn.com.jcda.exframe.MainFrame.actionPerformed(MainFrame.java:121) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6216) at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
suciver 2013-01-23
  • 打赏
  • 举报
回复
是哪里溢出的是List集合的溢出还是加入excel文件的溢出

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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