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;
    }
相关推荐
hx86227几秒前
Java MySQL 连接
java·mysql·adb
lpfasd1232 分钟前
Kubernetes (K8s) 底层早已不再直接使用 Docker 引擎了
java·docker·kubernetes
aq55356006 分钟前
SpringBoot有几种获取Request对象的方法
java·spring boot·后端
小郝 小郝18 分钟前
51 与32 单片机LED控制详解
c语言·开发语言·经验分享·学习·51单片机
星空露珠21 分钟前
迷你世界UGC3.0脚本Wiki全局函数
开发语言·数据库·算法·游戏·lua
金山几座41 分钟前
C#学习记录-类(Class)
开发语言·学习·c#
AsDuang1 小时前
Python 3.12 MagicMethods - 55 - __irshift__
开发语言·python
Detachym1 小时前
InsightFlow 服务配置优化与部署实践
java·spring boot·tomcat·maven·状态模式·jar
y = xⁿ1 小时前
【LeetCodehot100】T23:合并k个升序链表
java·数据结构·链表
流水武qin1 小时前
SpringAI多模态的基本使用
java·spring boot·spring·ai