EasyExcel如何解决临时文件过大问题

在使用EasyExcel导出excel的时候,会遇到占用大量磁盘的问题,当并发比较大时,会使服务器文件撑满。

原因排查

书写测试代码

   /**
     * 压缩临时文件
     * 在导出Excel且格式为xlsx的时候会生成一个临时的xml文件,会比较大,再磁盘不太够的情况下,可以压缩。
     * 当然压缩式耗费性能的
     */
    @Test
    public void compressedTemporaryFile() {
        log.info("临时的xml存储在:{}", FileUtils.getPoiFilesPath());
        File file = TestFileUtil.createNewFile("rare/compressedTemporaryFile" + System.currentTimeMillis()
            + ".xlsx");
        // 这里 需要指定写用哪个class去写
        try (ExcelWriter excelWriter = EasyExcel.write(file, DemoData.class).build()) {
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
            // 10万数据 确保有足够的空间
            for (int i = 0; i < 10000; i++) {
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                List<DemoData> data = data();
                excelWriter.write(data, writeSheet);
            }
            log.info("写入完毕,开始准备迁移压缩文件。");
        }
    }

    private List<DemoData> data() {
        List<DemoData> list = ListUtils.newArrayList();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

查看临时目录的文件大小

把断点设置在`log.info("写入完毕,开始准备迁移压缩文件。");` 这一行

可以看到1万3行的数据,就占用了17M内存,当数据量大了时候占用的磁盘会更大。

然后代码继续运行完成,会发现这个文件被删除了。

结论

所以这个文件占用是临时的,最后会自动删除。

解决方案

将这个临时的xml做压缩处理。配置方法如下:

    /**
     * 压缩临时文件
     * 在导出Excel且格式为xlsx的时候会生成一个临时的xml文件,会比较大,再磁盘不太够的情况下,可以压缩。
     * 当然压缩式耗费性能的
     */
    @Test
    public void compressedTemporaryFile() {
        log.info("临时的xml存储在:{}", FileUtils.getPoiFilesPath());
        File file = TestFileUtil.createNewFile("rare/compressedTemporaryFile" + System.currentTimeMillis()
            + ".xlsx");

        // 这里 需要指定写用哪个class去写
        try (ExcelWriter excelWriter = EasyExcel.write(file, DemoData.class).registerWriteHandler(
            new WorkbookWriteHandler() {

                /**
                 * 拦截Workbook创建完成事件
                 * @param context
                 */
                @Override
                public void afterWorkbookCreate(WorkbookWriteHandlerContext context) {
                    // 获取到Workbook对象
                    Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
                    // 只有SXSSFWorkbook模式才会生成临时文件
                    if (workbook instanceof SXSSFWorkbook) {
                        SXSSFWorkbook sxssfWorkbook = (SXSSFWorkbook)workbook;
                        // 设置临时文件压缩,当然这个会浪费cpu性能 但是临时文件会变小
                        sxssfWorkbook.setCompressTempFiles(true);
                    }
                }
            }).build()) {
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
            // 10万数据 确保有足够的空间
            for (int i = 0; i < 10000; i++) {
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                List<DemoData> data = data();
                excelWriter.write(data, writeSheet);
            }
            log.info("写入完毕,开始准备迁移压缩文件。");
        }
    }

重新运行

可以看到临时文件由17M变成了1.2M。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庄家钜Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值