(记)Excel导出优化之路

本文记录了一款基于Spring Boot的Excel导出组件的优化历程,从简单的Apache POI实现到支持异步、分页导出,有效降低了内存占用和提高了性能。对比了与EasyExcel的差异,并提供了优化后的内存和耗时数据。
摘要由CSDN通过智能技术生成

(记)Excel导出优化之路

经过了几个月的迭代,项目上的导出组件逐渐完善,想以本篇文章来记录项目上的导出组件的优化过程。

Excel导出组件是一个注解驱动的spring-boot-starter导出组件,利用Spring AOP拦截controller中的GET方法的查询API,并通过注解声明在DTO上来表示数据与excel中的映射关系和单元格属性,依赖于Apache POI完成excel数据填充的工作。

  • 与easyexcel比较

easyexcel提供了非常简单方便的导出api,支持注解驱动的导出配置,以及excel的读取和写入api,且声称在内存占用上消耗非常少。

Excel导出组件支持注解驱动的导出配置,而同时也提供了相对灵活的低层api,另外,Excel导出组件还支持异步,并封装了HTTP下载逻辑,在使用时无需关心文件下载的流操作。

Excel导出组件的API在单一需求的导出场景下更具优势(基于数据库查询的导出场景)。

Excel导出组件支持灵活分页导出,可根据配置调整,减少内存占用。

声明

由于源码逻辑比较复杂,看起来比较晦涩难懂,这里我手写了一个简单的demo,以及通过监控工具、统计数据来逐步分析和优化,感兴趣的可以下载源码跑看看。

环境准备:

Jdk8

Maven

Idea

项目地址:

Demo代码已上传至个人Github:https://github.com/XCXCXCXCX/export-optimization

优化之路

  • 传统POI导出

导出组件的诞生就是为了简化业务团队的开发工作,减少代码量,基于aop做出来的第一版,使用了Apache POI做excel数据填充的工作。

使用示例:

@GetMapping
public List<UserDTO> list() {
   
  return userService.list();
}


@GetMapping
@Export
public List<UserDTO> export() {
   
  return userService.list();
}

// 同时需要在UserDTO上声明数据填充映射关系和属性
// 简单示例如下
@ExportDTO
class UserDTO {
   
  
  @ExportColumn(column="id", width=100)
  private long id;
  
  @ExportColumn(column="name", color = Color.RED)
  private String name;
  
}

第一版的逻辑非常简单:

  1. 查询list数据
  2. 将list数据填充到一个excel的一个sheet中
  3. 设置excel下载响应头,写入响应流并结束响应

第一版基本能满足一些小项目的需求。

代码demo如下:

public class ExcelExporterV1 implements ExcelExporter {
   

    private List<String> data;

    public ExcelExporterV1(List<String> data) {
   
        this.data = data;
    }

    @Override
    public void export0() {
   
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        SXSSFSheet sheet = workbook.createSheet("sheet0");;
        for (int i = 0; i < data.size(); i++) {
   
            int index = i / 1000000;
            if (index > workbook.getNumberOfSheets() - 1) {
   
                workbook.createSheet("sheet" + index);
            }
            sheet = workbook.getSheetAt(index);
            SXSSFRow row = sheet.createRow(i);
            SXSSFCell cell = row.createCell(0);
            cell.setCellValue(data.get(i));
        }
        try {
   
            sheet.flushRows();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
        File file = Static.getFile("v1-" + UUID.randomUUID() + ".xlsx");
        try (FileOutputStream fos = new FileOutputStream(file)){
   
            workbook.write(fos);
        } catch (IOException e) {
   
            e.printStackTrace()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java导出几百万个Excel录,可以采取以下方法: 1. 采用第三方库:使用Apache POI或jxls等第三方库可以方便地在Java中操作Excel文件。这些库提供了丰富的API和功能,可以轻松地创建、编辑和导出Excel文件。可以使用内存映射技术将数据写入文件,以提高性能和效率。 2. 分批次导出:将几百万个录分成适量的批次,通过循环遍历每个批次,将数据逐批次写入Excel文件。这种方式可以减少内存占用并提高导出速度。 3. 多线程处理:使用多线程技术可以提高导出的效率。将数据分成多个部分,每个线程负责处理其中一部分的数据,然后将结果合并到最终的Excel文件中。合理地控制线程数和线程池的使用,可以最大限度地发挥多线程的优势。 4. 优化导出过程:在导出过程中,可以通过优化一些步骤来提高导出速度。例如,可使用内存缓存技术,将数据缓存到内存中,减少对数据库或其他数据源的频繁访问。还可以使用批量插入的方式将数据一次性写入到Excel文件,而不是逐条插入。 5. 压缩导出文件:如果导出Excel文件比较大,可以考虑使用压缩算法对导出文件进行压缩。这样可以节省磁盘空间,并降低文件的传输时间。 总结起来,要在Java导出几百万个Excel录,需要借助第三方库和合理的优化策略。综合运用分批次导出、多线程处理、优化导出过程和压缩导出文件等方法,可以提高导出的效率和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值