JAVA导出exce大数据量发生OOM异常
一般来说出excel的方式,一种是poi方式的,一种是jxl方式的。这两种方式支持大量数据导出都有一定的问题,因此试图寻找一个新办法,找到了easyexcel
easyexcel说明
1. 快速、简单避免OOM的java处理Excel工具
2. java解析、生成Excel比较有名的框架有Apache poi、jxl。
3. 但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,
4. 但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,
5. 内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,
6. 能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,
7. 再大的excel不会出现内存溢出,03版依赖POI的sax模式。
8. 在上层做了模型转换的封装,让使用者更加简单方便
easyexcel示例
如下是需要的一些包
easyexcel-1.0.4.jar
poi-ooxml-3.17.jar
xmlbeans-2.6.0.jar
commons-compress-1.14.jar
poi-scratchpad-3.17.jar
poi-ooxml-schemas-3.17.jar
poi-excelant-3.17.jar
poi-examples-3.17.jar
poi-3.17.jar
commons-collections4-4.1.jar
代码实例
public class ExcelTest extends UnitTest{
@org.junit.Test
public void writeExcelOneSheetOnceWrite() throws IOException {
// 生成EXCEL并指定输出路径
OutputStream out = new FileOutputStream("E:\\temp\\withoutHead1.xlsx");
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
// 设置SHEET
Sheet sheet = new Sheet(1, 0);
sheet.setSheetName("sheet1");
// 设置标题
Table table = new Table(1);
List<List<String>> titles = new ArrayList<List<String>>();
titles.add(Arrays.asList("用户ID"));
titles.add(Arrays.asList("名称"));
titles.add(Arrays.asList("年龄"));
titles.add(Arrays.asList("张三1"));
titles.add(Arrays.asList("张三2"));
titles.add(Arrays.asList("张三3"));
titles.add(Arrays.asList("张三4"));
titles.add(Arrays.asList("张三5"));
titles.add(Arrays.asList("张三6"));
titles.add(Arrays.asList("张三7"));
titles.add(Arrays.asList("张三8"));
titles.add(Arrays.asList("张三9"));
titles.add(Arrays.asList("张三10"));
titles.add(Arrays.asList("张三11"));
titles.add(Arrays.asList("张三12"));
titles.add(Arrays.asList("张三13"));
titles.add(Arrays.asList("张三14"));
titles.add(Arrays.asList("张三15"));
titles.add(Arrays.asList("张三16"));
titles.add(Arrays.asList("张三17"));
titles.add(Arrays.asList("张三18"));
titles.add(Arrays.asList("张三19"));
titles.add(Arrays.asList("张三20"));
titles.add(Arrays.asList("生日"));
table.setHead(titles);
// 查询数据导出即可 比如说一次性总共查询出100条数据
List<List<String>> userList = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
userList.add(Arrays.asList("ID_" + i,
"小明" + i,
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
String.valueOf(i),
new Date().toString()));
}
writer.write0(userList, sheet, table);
writer.finish();
}
思考问题的思路
我们在做大数据导出的时候,需要考虑三个问题
1. 数据库能不能撑住 查询大量数据对数据库是否造成困扰?
2. java能不能撑住,你的对象拿出来,放到内存里,Java会不会困扰?
3. 给excel导出数据,java操作excel的这个过程能不能撑住,它是否困扰?
本文是为了解决第3个问题的。
如果你的第1和第2问题,无法解决。
导出大量数据excel仍然是导致问题的,比如cpu飚高,比如内存耗尽。
还有更深一层次的哲学思想
如果可能,不要导出excel,而要导出csv,然后自己转,因为csv快的多。
当然产品经理可能会不满意,不过比起崩溃来,能用就是最基本原则。
本文介绍了在JAVA处理大数据量Excel导出时遇到的OOM异常,推荐了EasyExcel作为解决方案。EasyExcel是一个轻量级、避免OOM的Java Excel处理工具,相比Apache POI,它降低了内存消耗,特别适合处理大文件。文章提供了EasyExcel的快速说明,示例所需依赖包,以及在处理大数据导出时应考虑的三个方面,强调在数据库和Java内存允许的情况下,优先考虑导出CSV格式以提高效率。
421





