压缩流使用

压缩流

场景:需要将一些数据,以及这些数据关联的附件压缩下载,数据导出为一个Excel,附件导出到一个文件夹中

这里使用easyexcel 导出excel 从华为云 obs 下载附件

并交给浏览器

java 复制代码
public void downloadAllEliminate(HttpServletResponse response) throws IOException {

    // 响应头的设置
    response.reset();
    response.setCharacterEncoding("utf-8");
    response.setContentType("multipart/form-data");
    // 设置压缩包的名字
    // 解决不同浏览器压缩包名字含有中文时乱码的问题
    String downloadName = System.currentTimeMillis()+".zip";
    response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");


    // 数据
    List<CurrentTransactionsCountDetailsResult> allEliminate = baseMapper.getAllEliminate();
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("static/往来挂账-剔除.xlsx");

    // excel 输出流
    ByteArrayOutputStream outputStream1 = new ByteArrayOutputStream();
    ExcelWriter excelWriter = EasyExcel.write(outputStream1).withTemplate(inputStream).build();
    WriteSheet writeSheet = EasyExcel.writerSheet("往来挂账明细").build();
    FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).forceNewRow(Boolean.TRUE).build();
    excelWriter.fill(new FillWrapper("list", allEliminate), fillConfig, writeSheet);
    excelWriter.finish();//关闭流


    // 设置压缩流:直接写入response,实现边压缩边下载
    ZipOutputStream zipos = null;
    try {
        zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
        zipos.setMethod(ZipOutputStream.DEFLATED); // 设置压缩方法
    } catch (Exception e) {
        e.printStackTrace();
    }

    // 将excel写入
    zipos.putNextEntry(new ZipEntry("往来挂账-剔除.xlsx"));
    byte[] buffer = outputStream1.toByteArray();
    zipos.write(buffer, 0, buffer.length);
    zipos.closeEntry();

    // 拿到所有文件, 并写入压缩流
    List<Map<String, String>> allEliminateFileName = baseMapper.getAllEliminateFileName();
    String filePath = "附件/";
    for (Map<String, String> stringStringMap : allEliminateFileName) {
        InputStream is = obsUtil.getInputStream(stringStringMap.get("path"), CurrentTransactionsCountController.filePath);
        zipos.putNextEntry(new ZipEntry(filePath + stringStringMap.get("fileName")));

        byte[] bufferTo = new byte[2048]; // 更大的缓冲区通常能提高效率
        int length;
        while ((length = is.read(bufferTo)) != -1) {
            zipos.write(bufferTo, 0, length); // 直接写入zipos
        }

        is.close();
        zipos.closeEntry();
    }
    // 确保所有条目都已写入,并刷新缓冲区
    zipos.flush();

    // 关闭流
    try {
        zipos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }


}