当前位置:   article > 正文

常用的模板excel导出(二)之批量导出多文件、压缩成zip文件流输出_将多个outputstream导出到压缩包

将多个outputstream导出到压缩包

一、业务场景

最近在业务中,做了系统模块二级页面的订单导出功能,后续客户提了需求想要在一级页面做个批量导出配合多选框使用,实现多订单导出。具体的分析处理如下

二、业务分析

1、刚接到需求的时候,是想用接收前端传来的数组,循环获取相应订单的详情,依次写入文件流,输出多条excel记录,后续编写过程中,碰到流在第一次导出后就关闭了、以及会频繁弹框选择文件路径问题。
2、后面讨论后,交互效果定为批量导出的.xlsx文件,转成zip文件流,以zip格式导出。

三、解决方案

1、具体的模板导出需要的配置、jar引入,可以参考之前的文章 常用的模板excel导出(一)
2、相应的工具类代码、业务逻辑代码如下
    /**
     * 批量导出至zip格式
     *
     * @param dto 主键数组
     * @return 操作结果
     */
    public ServiceResponse<String> exportBatchbyZip(OrderExportBatchParam dto, HttpServletResponse response) {

        //1、获取导出的excel模板文件
        String templateExcelFileName = "name.xlsx";
        InputStream templateExcelInputStream = this.getClass().getClassLoader().getResourceAsStream("template" + File.separatorChar + templateExcelFileName);

        //2、校验
        if (ObjectUtils.isEmpty(templateExcelInputStream)) {
            return ServiceResponse.paramError("模板文件不存在!");
        }
        ByteArrayOutputStream outputStream = null;
        ZipOutputStream zipOut = null;
        try {
        
            //3、处理导出的zip 文件名称,避免中文乱码
            response.setContentType("application/octet-stream; charset=UTF-8");
            String encodedFileName = URLEncoder.encode("订单导出.zip", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + encodedFileName);
            zipOut = new ZipOutputStream(response.getOutputStream());

            //4、复制输入模板文件流,避免第一次以后读取为空问题
            ByteArrayOutputStream bos = cloneInputStream(templateExcelInputStream);
            for (Long id : dto.getIds()) {
                //5、获取数据源、完善模板参数
                OrderInfoVO vo = getOrderInfo(id);
                Map<String, Object> dataMap = new HashMap<String, Object>();
                dataMap.put("name", vo.getName());
                ......
                //涉及子表数据则添加相应的list
                List<ListVO> voList = vo.getList();

                //6、流创建
                InputStream copyInputStream = new ByteArrayInputStream(bos.toByteArray());
                outputStream = new ByteArrayOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(copyInputStream).excelType(ExcelTypeEnum.XLSX).build();

                //7、设置 zip 中的每个文件名称
                zipOut.putNextEntry(new ZipEntry("【" + vo.getName()+"】订单.xlsx"));

                //8、读取excel
                WriteSheet writeSheet = EasyExcel.writerSheet().build();

                //9、自动填充(涉及父子表模板样式,自动填充打开,会根据模板自增行数循缓 voList 赋值)
                FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

                //10、填充 list 数据 填充 map 数据
                excelWriter.fill(voList , fillConfig, writeSheet);
                excelWriter.fill(dataMap, writeSheet);

                //11、流处理
                excelWriter.finish();
                outputStream.writeTo(zipOut);
                outputStream.flush();
                outputStream.close();
                zipOut.closeEntry();
                copyInputStream.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ServiceResponse.paramError("操作失败:" + e.getMessage());
        } finally {
            if (null != outputStream) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != zipOut) {
                try {
                    zipOut.flush();
                    zipOut.finish();
                    zipOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return ServiceResponse.paramError("操作失败:" + e.getMessage());
                }
            }
        }
        return ServiceResponse.ok("操作成功");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

    /**
     * 复制InputStream
     *
     * InputStream inputStream = new ByteArrayInputStream(ByteArrayOutputStream.toByteArray());
     * @param input
     * @return
     */
    public static ByteArrayOutputStream cloneInputStream(InputStream input) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = input.read(buffer)) > -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();
            return baos;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
3、本地postman测试后的结果如下:

在这里插入图片描述

四、 尾言

感谢阅读,后续也会有相应的更新。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/216030
推荐阅读
相关标签
  

闽ICP备14008679号