流式导出与默认导出不同之处在于:流式导出采用生产者消费者模式,允许分批获取数据,分批写入Excel,且默认采用SXSSF模式,内存占用量极低,真正意义上实现海量数据导出,另外,流式导出支持zip压缩包等独有特性。

    使用流式导出分为三步:

    1. 配置
    1. DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
    2. .of(ArtCrowd.class) // 如导出Map类型数据,请使用of(Map.class)
    3. .threadPool(Executors.newFixedThreadPool(10))// 线程池,可选
    4. .templateHandler(FreemarkerTemplateHandler.class)// 追加模板数据,可选,适合极度个性化数据导出
    5. .capacity(10_000)// 容量设定,在主动划分excel使用,可选
    6. .start();

    如需向已存在Excel中追加数据,请使用of(ArtCrowd.class, Paths.get("/user.xlsx"))of(ArtCrowd.class, new FileInputStream(new File("/user.xlsx"))),需要注意的是,追加的文件内容必须和Bean一致,且目前暂不支持多sheet追加。

    1. 数据追加

    append参数可为列表,也可为单个数据,建议使用单个数据追加,如Bean、Map

    1. // streamExcelBuilder.append(data);
    2. streamExcelBuilder.asyncAppend(this::getDataList); // 异步追加,屏蔽多线程处理细节

    在某些情况下,可能需要个性化的表头,或者汇总等等,这些需求可能会涉及合并行、列、样式等复杂布局,DefaultStreamExcelBuilder本身对Bean的能力不足以支撑,版本3.6.0以及以后,DefaultStreamExcelBuilder支持模板的追加,在模板中定义复杂布局,追加模板方式如下:

    1. DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
    2. .of(ArtCrowd.class)
    3. .templateHandler(FreemarkerTemplateHandler.class)// 追加模板数据,可选,适合极度个性化数据导出
    4. .start();
    5. Map<String,Object> dataMap=new HashMap<>();
    6. dataMap.put("title","测试");
    7. streamExcelBuilder.append("/templates/xxx.ftl",dataMap);
    1. 完成构建
    1. Workbook workbook = streamExcelBuilder.build();

    如需最大化提升导出性能,请调用noStyle()方法全面禁止样式.

    DefaultStreamExcelBuilder默认采用SXSSF模式(内存占用低)导出,该模式下不支持自动列宽.

    附件导出示例:

    try-with-resource方式不可返回Workbook,因为在close方法中会关闭Wrokbook

    1. try (DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
    2. .of(ArtCrowd.class)
    3. .threadPool(Executors.newFixedThreadPool(10))
    4. .start()) {
    5. for (int i = 0; i < 100; i++) {
    6. // 数据追加
    7. streamExcelBuilder.asyncAppend(this::getDataList);
    8. }
    9. // 最终构建
    10. Workbook workbook = defaultExcelBuilder.build();
    11. AttachmentExportUtil.export(workbook, "艺术生信息", response);
    12. }

    多文件导出示例:

    设置Excel容量(capacity(10_000)),如设置,则当Excel的行数达到容量后产生新的Excel

    1. try (DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
    2. .of(ArtCrowd.class)
    3. .threadPool(Executors.newFixedThreadPool(10))
    4. .capacity(10_000)
    5. .start()) {
    6. ......
    7. // 最终构建
    8. List<Path> paths = streamExcelBuilder.buildAsPaths();
    9. // do something
    10. }

    zip导出示例:

    设置Excel容量(capacity(10_000))

    1. try (DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
    2. .of(ArtCrowd.class)
    3. .threadPool(Executors.newFixedThreadPool(10))
    4. .capacity(10_000)
    5. .start()) {
    6. ......
    7. // 最终构建
    8. Path zip = streamExcelBuilder.buildAsZip("test");
    9. AttachmentExportUtil.export(zip,"finalName.zip",response);
    10. }

    导出使用注解

    1. @ExcelModel(includeAllField,excludeParent,workbookType,sheetName,useFieldNameAsTitle,defaultValue)
    2. @IgnoreColumn
    3. @ExcelColumn(title,order,format,groups,defaultValue)

    对应注解详情请见:注解