前言
看了好几篇文章介绍导出大数据到excel,但是都是通过xml文件,需要熟悉源码,纠结了,之前没搞过xml一时半会肯定搞不定啊,今天就简单的介绍下不用xml也能实现大数据导出到xls文件。
优化思路
通常excel导出都是直接获取到excel文件。之后直接插入数据库中查询到的数据,随着数据量变大,每次插入数据肯定消耗更多的时间解析整个excel文件,效率就会越来越慢,甚至导致内存溢出,这种情况下,就需要考虑能不能用临时文件先写入一部分数据,之后通过io的形式插入到之前的excel文件呢。经过查看jxl源码,惊喜的发现,居然是支持的!
引入JAR
ivy引入
<dependency org="jxl" name="jxl" rev="2.6.12"/>
maven引入
<dependency>
<groupId>jxl</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
实现代码
WorkbookSettings wbSetting = new WorkbookSettings();
wbSetting.setUseTemporaryFileDuringWrite(true);
//临时文件夹的位置
wbSetting.setTemporaryFileDuringWriteDirectory(new File(localTempFile));
WritableWorkbook wwb;
if(sheet == 1){ // sheet为1创建excel文件
wwb = Workbook.createWorkbook(new File(filePath), wbSetting);//采用临时文件形式生成数据
}else{
FileInputStream in = new FileInputStream(new File(filePath));//读取已经生成的excel文件
Workbook wb= Workbook.getWorkbook(in); // 解析input流为excel对象
wwb= Workbook.createWorkbook(new File(filePath), wb, wbSetting);//采用临时文件形式创建新对象,并且新对象会包含之前生成的excel对象
}
代码说明:
因为xls文件对每个sheet有最大6万多行的限制,所以不得不采用多个sheet进行写入,所以就出现了上面 sheet为1的条件判断。
WorkbookSetting类提供了临时文件来存储数据,换句话说就是先把要生成的数据写入tmp类型的临时文件,写完之后在统一写入已经存在的excel,所以生成数据时候只需要考虑本临时文件内的数据逻辑,节省大量的excel分析计算过程,效率自然会提高很多。
WorkbookSetting类提供了临时文件来存储数据,换句话说就是先把要生成的数据写入tmp类型的临时文件,写完之后在统一写入已经存在的excel,所以生成数据时候只需要考虑本临时文件内的数据逻辑,节省大量的excel分析计算过程,效率自然会提高很多。
重要WorkbookSetting参数介绍
gcDisabled:设置是否进行wwb调用close方法后后是否进行垃圾回收,建议设置为true,不进行垃圾回收,因为频繁垃圾回收比较耗性能
void close(boolean cs) throws IOException, JxlWriteException {
jxl.write.biff.CompoundFile cf = new jxl.write.biff.CompoundFile(this.data, this.data.getPosition(), this.outputStream, this.readCompoundFile);
cf.write();
this.outputStream.flush();
this.data.close();
if(cs) {
this.outputStream.close();
}
this.data = null;
if(!this.workbookSettings.getGCDisabled()) {//设置为false就会调用垃圾回收
System.gc();
}
}
initialFileSize:默认设置临时文件初始大小为5m,可以根据实际预计的临时文件大小重新设置
useTemporaryFileDuringWrite:是否使用自定义临时文件位置,如果设置为false,使用String tempdir = System.getProperty("jxl.temporaryfileduringwritedirectory");
setTemporaryFileDuringWriteDirectory自定义文件位置,使用结束后,系统会自动删除临时文件
其余的还有好多个参数,可以去类里面自己看看,这里不再一一介绍。
结束语
采用临时文件也是没有办法,系统设计就是导出excel,所以只能是想办法优化。当前1G内存情况下,导出百万级别的数据问题不是很大。
个人不推荐导出excel文件,生成过程占用内存过大,并且上传、下载这些文件过程通常比较耗时,不认为是很好的解决方案。推荐导出csv、txt格式。
以上是个人的一个解决办法,如果有好的办法,可以留言,本人再进行相应的优化。