EasyExcel多线程导出并实现Zip压缩

前言:之前实现的需求由于导出时需要的时间过于长,需要优化采用多线程的方式进行导出

更改之后的代码:

首先创建excel的临时文件,并写入。然后创建线程池,调用zipArchiveOutputStream来写入图片和excel

java 复制代码
@PostMapping("/export3")
    public void exportZip(HttpServletResponse response,
                       @RequestParam(value = "startTime",required = false)String startTime,
                       @RequestParam(value = "endTime",required = false)String endTime,
                       @RequestParam(value = "deviceName",required = false)String deviceName) throws IOException {
        List<CutterImageVO> cutterImageVOList = cutterImageService.getCutterImageList(startTime,endTime,deviceName);
        long start = System.currentTimeMillis();
        String zipFileName = "豁口图片数据";
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName + ".zip", "UTF-8"));

        //创建excel临时文件
        final File tempFile = File.createTempFile("tempExcel", ".xls");
        EasyExcel.write(tempFile.getCanonicalPath(),CutterImageVO.class)
                .excelType(ExcelTypeEnum.XLS)
                .registerWriteHandler(new ExcelHyperlinkHandler(1, new int[]{7}))
                .sheet("豁口图片数据")
                .doWrite(cutterImageVOList);
        logger.info("临时文件所在的本地路径:" + tempFile.getCanonicalPath());


        ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), new MyRejectedExecutionHandler());
        ParallelScatterZipCreator parallelScatterZipCreator = new ParallelScatterZipCreator(executor);
        OutputStream outputStream = response.getOutputStream();
        ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);
        zipArchiveOutputStream.setEncoding("UTF-8");

        try {
            for (int i = 0; i <= cutterImageVOList.size(); i++) {
                int finalI = i;
                String fileName = null;
                if (finalI == cutterImageVOList.size()) {
                    fileName = "豁口图片数据.xls";
                } else {
                    fileName = cutterImageVOList.get(i).getImageUrl();
                }
                String finalFileName = fileName;
                final InputStreamSupplier inputStreamSupplier = () -> {
                    try {
                        InputStream inputStream = null;
                        if (finalI == cutterImageVOList.size()) {
                            inputStream = new FileInputStream(tempFile.getCanonicalPath());
                        } else {
                            inputStream = minioUtil.getDownloadInputStream(finalFileName);
                        }
                        return inputStream;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return new NullInputStream(0);
                    }
                };
                ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(fileName);
                zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);
                zipArchiveEntry.setUnixMode(UnixStat.FILE_FLAG | 436);
                parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);
            }
            parallelScatterZipCreator.writeTo(zipArchiveOutputStream);
        }catch(Exception e){
            log.error("文件流读取失败",e);
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(zipArchiveOutputStream);
            IOUtils.closeQuietly(outputStream);
        }
        //程序退出时删除临时文件
        tempFile.deleteOnExit();
        long end = System.currentTimeMillis();
        log.info("耗时:"+(end-start));
    }

Minio工具类

java 复制代码
public InputStream getDownloadInputStream(String fileName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
       InputStream is = client.getObject(GetObjectArgs.builder()
               .bucket(minioConfig.getBucketName())
               .object(fileName)
               .build());
       return is;
    }
相关推荐
Python大数据分析@3 分钟前
CLI一键采集,使用Python搭建TikTok电商爬虫Agent
开发语言·爬虫·python
@小码农27 分钟前
2026年3月Scratch图形化编程等级考试一级真题试卷
开发语言·数据结构·c++·算法
这儿有一堆花28 分钟前
住宅代理(Residential Proxy)技术指南
开发语言·数据库·php
one_love_zfl37 分钟前
java面试-微服务组件篇
java·微服务·面试
一只大袋鼠40 分钟前
Java进阶:CGLIB动态代理解析
java·开发语言
秦ぅ时41 分钟前
保姆级教程|OpenAI tts-1-hd模型调用全流程(Python+curl+懒人用法)
开发语言·python
Eiceblue1 小时前
使用 C# 将 Excel 转换为 Markdown 表格(含批量转换示例)
开发语言·c#·excel
环流_1 小时前
HTTP 协议的基本格式
java·网络协议·http
爱滑雪的码农1 小时前
Java基础十三:Java中的继承、重写(Override)与重载(Overload)详解
java·开发语言
Java面试题总结1 小时前
使用 Python 设置 Excel 数据验证
开发语言·python·excel