java 百万千万级别excel数据导出问题

基础:

  Apache POI基于DOM方式进行解析,将文件直接加载内存,所以速度较快,适合Excel文件数量不大的应用场景。

 Alibaba EasyExcel采用逐行读取的解析模式,将每一行的解析结果以观察者模式通知处理(AnalyEventListener),所以比较适合数据体量较大的Excel文件解析。

当前问题:

        导出慢、OutOfMemoryError内存溢出

解决思路:

        使用批量写入或导出,不要一次性将数据读取到内存或一次性读写数据库

        导出:将数据分页读取,每次读取1万条数据,在读取数据的过程中,将数据转换成CSV格式,然后到了一定大小,就写入到CSV文件,这样就可以避免内存溢出。

        导入: Apache POI是直接一次性读取到内存, 所以建议使用阿里的EasyExcel,它是采用逐行读取模式

EasyExcel读取示例

EasyExcel.read("test.xlsx", Test.class,new AnalysisEventListener<Test>() {
    @Override
    public void invoke(Test test, AnalysisContext arg1) {
        // 读取每条数据
        orderList.add(order);
    }
 
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 读取到列头
        System.out.println(headMap);
    }
 
    @Override
    public void doAfterAllAnalysed(AnalysisContext arg0) {
        // 读取完毕
        System.out.println("END");
    }
}).sheet().doRead();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果需要支持百万级别数据量的 Excel 导出,我们可以使用 SXSSF 和 XSSF 的组合。 XSSF 是 Apache POI 中用于操作 Excel 2007 及以上版本的 API,它使用内存映射文件的方式操作 Excel 文件,因此可以处理大型 Excel 文件。但是,由于 XSSF 会将整个 Excel 文件读入内存,因此对于百万级别数据量,XSSF 可能会导致内存溢出等问题。 SXSSF 是 XSSF 的一种变体,它使用流式方式操作 Excel 文件,可以在生成 Excel 文件时不将整个文件读入内存,因此可以处理极大规模的数据。SXSSF 的操作方式与 XSSF 相似,只是 SXSSF 没有缓存,需要将数据写入硬盘而不是内存中。 下面是一个示例代码,演示如何使用 SXSSF 和 XSSF 的组合实现百万级别数据量的 Excel 导出: ```java public void exportExcel(List<User> userList, OutputStream outputStream) throws IOException { // 创建 Excel 工作簿对象 Workbook workbook = new SXSSFWorkbook(); // 创建 Sheet 对象 Sheet sheet = workbook.createSheet("用户列表"); // 创建表头行 Row headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("ID"); headerRow.createCell(1).setCellValue("姓名"); headerRow.createCell(2).setCellValue("性别"); headerRow.createCell(3).setCellValue("年龄"); // 填充数据行 for (int i = 0; i < userList.size(); i++) { User user = userList.get(i); Row dataRow = sheet.createRow(i + 1); dataRow.createCell(0).setCellValue(user.getId()); dataRow.createCell(1).setCellValue(user.getName()); dataRow.createCell(2).setCellValue(user.getGender()); dataRow.createCell(3).setCellValue(user.getAge()); // 每写入1000条数据,刷新一次缓存 if (i % 1000 == 0) { ((SXSSFSheet) sheet).flushRows(); } } // 将工作簿写入输出流 workbook.write(outputStream); // 关闭工作簿 workbook.close(); } ``` 以上示例代码中,我们使用 `SXSSFWorkbook` 创建了一个 SXSSF 工作簿对象,并在填充数据时,每写入 1000 条数据时,刷新一次缓存。这样可以避免将整个 Excel 文件读入内存而导致内存溢出等问题。 调用示例代码: ```java List<User> userList = new ArrayList<>(); // 添加百万级别的用户数据 // ... OutputStream outputStream = new FileOutputStream("用户列表.xlsx"); exportExcel(userList, outputStream); outputStream.close(); ``` 以上示例代码中,我们添加了百万级别的用户数据,并将其导出到 `用户列表.xlsx` 文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值