使用ZipOutputStream实现web端批量下载文件到浏览器

1、需求场景

平时我们开发web应用时可能会遇到用户在界面选择下载多个报表,点击下载按钮后需要批量下载这些文件到浏览器。但是一般情况下,页面一次点击只能触发一个文件的下载,所以无法实现上述诉求。

2、解决方案

针对上述的问题我们可以借助java.util.zip.ZipOutputStream这个类来实现该功能,具体的我们可以使用该类将多个报表文件压缩到一个zip包中,然后将这个zip包写回到浏览器。

3、代码实现

3.1、zip压缩代码
 /**
     * 
     * @param files  需要压缩的文件列表
     * @param zipFile  压缩后的文件
     */
    public static void ZipMultiFile(List<File> files, File zipFile) {
        try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile))) {

            for (File file : files) {
                try (FileInputStream fis = new FileInputStream(file);) {
                    zipOut.putNextEntry(new ZipEntry(file.getName()));
                    int temp;
                    byte[] buf = new byte[1024];
                    while ((temp = fis.read(buf)) != -1) {
                        zipOut.write(buf, 0, temp);
                    }
                    zipOut.closeEntry();
                    zipOut.flush();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.2、zip压缩文件写回浏览器代码
 /**
     * 多文件下载
     * @param files
     * @param zipFile
     * @param response
     */
    public static void multiDownload(List<File> files,
                                     File zipFile,
                                     HttpServletResponse response) {


        response.reset();
        // 设置response的Header
        response.setCharacterEncoding("UTF-8");
        //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
        //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 告知浏览器文件的大小

        //设置响应格式,已文件流的方式返回给前端。
        response.setContentType("application/octet-stream");
        //生成压缩文件
        ZipMultiFile(files, zipFile);
        response.addHeader("Content-Length", String.valueOf(zipFile.length()));

        try (ServletOutputStream sos = response.getOutputStream();
             BufferedInputStream bis = new BufferedInputStream(new FileInputStream(zipFile))) {
            byte[] buff = new byte[1024 * 10];
            int index;
            while ((index = bis.read(buff, 0, buff.length)) != -1) {
                sos.write(buff, 0, index);
            }
            sos.flush();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值