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;
    }
相关推荐
嘻哈∠※6 小时前
0061基于 SpringBoot 的投稿与稿件处理系统设计与实现
java·spring boot·后端
WWJA王文举7 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
zhanghaha13147 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json
白狐_7987 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2588 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
码匠许师傅8 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
qq_448011168 小时前
C语言中的动态内存分配
c语言·开发语言·php
汉字萌萌哒9 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
arbboter9 小时前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
极创信息10 小时前
系统安全隐患全方位排查方案:标准化渗透测试全流程
java·opencv·struts·数据挖掘·eclipse·语音识别·hibernate