文件压缩、下载方法

  1. 文件下载方法
        @RequestMapping(value = "/download", method = RequestMethod.GET)
        @ResponseBody
        public ResponseEntity<InputStreamResource> download(){
          ResponseEntity<InputStreamResource> responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
          /*压缩包及其压缩文件夹路径*/
                String zipPath = filePath + File.separator + UUID.randomUUID() + File.separator + LocalDate.now();
                String zipPathName = zipPath + Constants.REPORT_FILENAME_EXT_ZIP;
                /*如果压缩的文件夹或者压缩文件不存在,则生成*/
                File zipFolder = new File(zipPath);
                if (!zipFolder.exists()) {
                    zipFolder.mkdirs();
                }
                File zipFile = new File(zipPathName);
                if (!zipFile.exists()) {
                    zipFile.createNewFile();
                }
                /*压缩需要下载的文件夹:第一个参数是压缩文件的路径,第二个参数是要压缩目录的路径*/
                compreSsion(zipPathName, new File(zipPath));
                   
                /*将文件装入流中*/
                FileSystemResource file = new FileSystemResource(zipPathName);
                /*如果文件流不为空,则允许下载*/
                if (file.exists()) {
                    HttpHeaders headers = new HttpHeaders();
                    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
                    headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
                    headers.add("Pragma", "no-cache");
                    headers.add("Expires", "0");
                    
                    return responseEntity
                            .ok()
                            .headers(headers)
                            .contentLength(file.contentLength())
                            .contentType(MediaType.parseMediaType("application/octet-stream"))
                            .body(new InputStreamResource(file.getInputStream()));
                }
                return null;
        }
    
  2. 文件压缩方法
        /**
         * 压缩文件夹
         * 压缩需要下载的文件夹:第一个参数是压缩文件的路径,第二个参数是要压缩目录的路径
         * @param zipFileName zip包路径
         * @param target      文件夹路径
         * @throws IOException
         */
    private static void compreSsion(String zipFileName, File target) throws IOException {
            logger.info("下载->压缩文件...");
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
            BufferedOutputStream bos = new BufferedOutputStream(out);
            zip(out, target, target.getName());
            bos.close();
            out.close();
            logger.info("下载->压缩完成");
        }
           
        /**
         * 压缩文件集合,将文件路径
         *
         * @param zipFileName zip路径
         * @param target      文件名list集合
         * @param path      文件对应的路径
         */
        public static void compreSsion(String zipFileName, List<String> target, String path) throws IOException {
            logger.info("月结账单下载->压缩文件...");
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
            BufferedOutputStream bos = new BufferedOutputStream(out);
            for (String s : target) {
                File folder = new File(path + File.separator + s);
                /*如果文件夹下的文件不为空,则继续执行*/
                if (Objects.nonNull(folder.list())) {
                    zip(out, folder, folder.getName());
                }
            }
            bos.close();
            out.close();
            logger.info("月结账单下载->压缩完成");
        }
        
    private static void zip(ZipOutputStream zout, File target, String name) throws IOException {
            //判断是不是目录
            if (target.isDirectory()) {
                File[] files = target.listFiles();
                if (files.length == 0) {//空目录
                    zout.putNextEntry(new ZipEntry(name + "/"));
                /*  开始编写新的ZIP文件条目,并将流定位到条目数据的开头。
                  关闭当前条目,如果仍然有效。 如果没有为条目指定压缩方法,
                  将使用默认压缩方法,如果条目没有设置修改时间,将使用当前时间。*/
                }
                for (File f : files) {
                    //递归处理
                    zip(zout, f, name + "/" + f.getName());
                }
            } else {
                zout.setEncoding("GBK");// 设置编码格式
                zout.putNextEntry(new ZipEntry(name));
                InputStream inputStream = new FileInputStream(target);
                BufferedInputStream bis = new BufferedInputStream(inputStream);
                byte[] b = new byte[8192];
                int length = 0;
                while ((length = bis.read(b)) != -1) {
                    /*网上找的是使用bis去写入,会导致下载的zip包解压后文件打不开,这里改成zip流写入就没问题*/
                    zout.write(b, 0, length);
                }
                bis.close();
            }
        }
    
  3. vue下载文件方法
    // 文件流下载通用方法,只能使用get请求
    window.open(window._global._BASEURL + '***/***?param=' + this.xxx);
       
    // 文件流下载通用方法,可以使用get或者post请求
    /*使用Blob,以本地方式保存文件。该方法会造成低版本的浏览器下载大文件时请求崩溃(测试版本为Chrome v65),如果考虑兼容,不推荐使用*/
    onDownload(param) {
            this.$httpExt().get('/report/excel?param=param', {
                xxx: this.searchForm.xxx,
                xxx: this.searchForm.xxx,
                xxx: this.searchForm.xxx,
            }, {
                /*注意:responseType应设置为:'arraybuffer',这样返回的文件流才会是二进制的,才能使用new Blob得到正确的文件*/
                responseType: 'arraybuffer'
            }).then(res => {
                    /*下载成功的提示语*/
                    if (res && res.status === 200) {
                        this.$message({
                            message: this.$t('文件正在下载,请稍后!'),
                            type: 'success',
                            duration: 2000
                        });
                        /*使用Blob,以本地方式保存文件。该方法会造成低版本的浏览器下载大文件时请求崩溃(测试版本为Chrome v65),如果考虑兼容,不推荐使用*/
                        const [, fileName] = res.headers['content-disposition'].split('=');
                        const blob = new Blob([res.data]);
                        //对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
                        //IE10以上支持blob但是依然不支持download
                        if ('download' in document.createElement('a')) {
                            const downloadElement = document.createElement('a'); /*创建a标签*/
                            const href = window.URL.createObjectURL(blob);
                            /*a标签添加属性*/
                            downloadElement.href = href;
                            downloadElement.download = decodeURI(fileName);
                            downloadElement.style.display = 'none';
    
                            document.body.appendChild(downloadElement);
                            downloadElement.click(); /*执行下载*/
                            document.body.removeChild(downloadElement); /*释放标签*/
                            window.URL.revokeObjectURL(href); /*释放url*/
                        } else {
                            navigator.msSaveblob(blob, fileName)
                        }
                    });
            }
        }
          
    /*参考来源:https://blog.csdn.net/qq_24607837/article/details/98196114*/
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值