Java打包ZIP压缩包文件下载

最近项目有需求,需要把管理中的数据,按照ID下载其附件,但由于附件较多,因此需要用压缩包的形式下载。

我们的文件都采用相对路径存储在远程FTP服务器。因此需要连接远程FTP服务器(正式环境存储在OSS服务器)

需要用到的对象如下:ZipOutputStream ZipEntry

ZipOutputStream下有多个ZipEntry。就像一个纸盒子里面有很多饼干,糖果等等。纸盒子就是输出流ZipOutputStream,饼干和糖果就是ZipEntry。商店把饼干和糖果装进(putNextEntry)纸盒子里系好然后卖给你

理解了概念,代码直接贴出来了。

代码如下:

步骤一:取数,得到文件名

    /**
     * 【下载附件】报价记录/报名记录
     * @param id
     */
    @GetMapping("/download/{id}")
    public void downloadAnnex(@PathVariable("id") Long id) {
        BiddingRecordDto brDto = biddingRecordFacede.getById(id);
        if(null == brDto){
            log.error("{}",brDto.toString());
            throw new CustomTipException("未查询到报价信息!");
        }
        List<String> imageAnnexs = new ArrayList<>();
        List<String> fileAnnexs = new ArrayList<>();
        if(!StringUtils.isEmpty(brDto.getImageAnnex())){
            imageAnnexs = JSONArray.parseArray(brDto.getImageAnnex()).toJavaList(String.class);
        }
        if(!StringUtils.isEmpty(brDto.getFileAnnex())){
            fileAnnexs = JSONArray.parseArray(brDto.getFileAnnex()).toJavaList(String.class);    
        }
        List<String> unionList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(imageAnnexs)){
            unionList.addAll(imageAnnexs);
        }
        if(!CollectionUtils.isEmpty(fileAnnexs)){
            unionList.addAll(fileAnnexs);
        }
        log.info(imageAnnexs.toString()+"\n"+fileAnnexs.toString());
        String fileName = UUID.randomUUID().toString();
        exportToBrowser(browsePath,fileName+".zip",unionList,response,request);

    }

步骤二:导出ZIP,输出到浏览器

    /**
     * 导出zip文件,输出到浏览器
     */
    public static void exportToBrowser(String browsePath,String fileName, List<String> annexPaths, HttpServletResponse response, HttpServletRequest request) {
        try {
            // 浏览器处理乱码问题
            String userAgent = request.getHeader("User-Agent");
            // filename.getBytes("UTF-8")处理safari的乱码问题
            byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes() : fileName.getBytes("UTF-8");
            // 各浏览器基本都支持ISO编码
            fileName = new String(bytes, "ISO-8859-1");
            // 文件名外的双引号处理firefox的空格截断问题
            response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
            response.setContentType("application/x-msdownload");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            doZIP(browsePath,annexPaths, response);
        } catch (Exception e) {
            log.info("下载失败!" + e);
        }
    }

步骤三:打包成压缩包

    /**
     * 压缩文件
     * @param browsePath 文件存储服务器路径
     * @param annexPaths 文件名称
     * @param response
     * @throws IOException
     */
    public static void doZIP(String browsePath,List<String> annexPaths,HttpServletResponse response) throws IOException{
        InputStream input = null;
        //定义压缩输出流
        ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
        for (String fileName : annexPaths) {
            //拼接相对路径成绝对路径
            String AnnexPath = browsePath+fileName;
            URL url = new URL(AnnexPath);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            input = connection.getInputStream();
            //压缩包中的子条目
            int i = fileName.lastIndexOf("/")+1;
            String name = fileName.substring(i);
            ZipEntry zipEntry = new ZipEntry(name);
            zipOut.putNextEntry(zipEntry);
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = input.read(buffer)) != -1) {
                zipOut.write(buffer, 0, len);
            }
            input.close();
        }
        zipOut.closeEntry();
        zipOut.close();
    }
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值