龙空技术网

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

庄家钜Java 180

前言:

而今你们对“java临时目录”可能比较重视,你们都需要分析一些“java临时目录”的相关资讯。那么小编在网摘上网罗了一些对于“java临时目录””的相关内容,希望看官们能喜欢,看官们一起来学习一下吧!

在使用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。

标签: #java临时目录