下载多个云文件云文件,打包成zip

个人笔记,欢迎指正

后端代码

// controller 层
@GetMapping("downloadContractFile/{contractId}")
public void downloadContractFile(HttpServletResponse response, @PathVariable String contractId) throws IOException {
    byte[] bytes = purContractService.downloadContractFile(contractId);
    genCode(response, bytes);
}

/**
 * 生成zip文件
 */
private void genCode(HttpServletResponse response, byte[] data) throws IOException
{
    response.reset();
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
    response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
    response.addHeader("Content-Length", "" + data.length);
    response.setContentType("application/octet-stream; charset=UTF-8");
    IOUtils.write(data, response.getOutputStream());
}

// service 层
@Override
public byte[] downloadContractFile(String contractId) {
    Map<String, String> filePath = new HashMap<>();

    // 合同文件
    Optional.ofNullable(baseMapper.selectById(contractId)).ifPresent(contract -> {
        filePath.put("合同正文", contract.getContractFile());
        filePath.put("合同附件", contract.getFilePath());
    });

    // 签订文件
    Optional.ofNullable(purContractSignedService.getOne(new LambdaQueryWrapper<PurContractSigned>().eq(PurContractSigned::getContractId, contractId)))
            .ifPresent(purContractSigned -> filePath.put("签订文件", purContractSigned.getSignedFilePath()));

    // 验收文件
    Optional.ofNullable(purContractAcceptanceService.list(new LambdaQueryWrapper<PurContractAcceptance>().eq(PurContractAcceptance::getContractId, contractId)))
            .ifPresent(acceptanceList -> {
                for (int i = 0; i < acceptanceList.size(); i++) {
                    PurContractAcceptance acceptance = acceptanceList.get(i);
                    filePath.put("验收文件(" + (i + 1) + ")", acceptance.getAcceptanceFile());
                }
            });

    // 结算文件
    Optional.ofNullable(purContractSettlementService.list(new LambdaQueryWrapper<PurContractSettlement>().eq(PurContractSettlement::getContractId, contractId)))
            .ifPresent(settlementList -> {
                for (int i = 0; i < settlementList.size(); i++) {
                    PurContractSettlement settlement = settlementList.get(i);
                    filePath.put("结算文件(" + (i + 1) + ")", settlement.getSettlementFilePath());
                }
            });

    // 归档文件
    Optional.ofNullable(purContractArchivesService.list(new LambdaQueryWrapper<PurContractArchives>().eq(PurContractArchives::getContractId, contractId)))
            .ifPresent(contractArchivesList -> {
                for (int i = 0; i < contractArchivesList.size(); i++) {
                    PurContractArchives archives = contractArchivesList.get(i);
                    filePath.put("归档文件(" + (i + 1) + ")", archives.getFilePath());
                }
            });


    ByteArrayOutputStream outputStream = this.compressFileToZip(filePath);

    return outputStream.toByteArray();
}

/**
 * 压缩成zip文件
 *
 * @param filePath
 * @return
 */
private ByteArrayOutputStream compressFileToZip(Map<String, String> filePath) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try(ZipOutputStream zip = new ZipOutputStream(outputStream)) {
        for (String key : filePath.keySet()) {
            String fileURL = filePath.get(key);
            try {
                if (StringUtils.isEmpty(fileURL)) continue;
                // 下载每个文件
                URL url = new URL(fileURL);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.connect();

                // 检查响应码,确保文件成功下载
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // 获取文件流
                    InputStream inputStream = connection.getInputStream();

                    // 从 URL 获取文件名 (从路径中提取文件名)
                    String fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1);
                    // 将文件写入到 ZipEntry
                    zip.putNextEntry(new ZipEntry(key + "_" + fileName));

                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = inputStream.read(buffer)) > 0) {
                        zip.write(buffer, 0, length);
                    }

                    zip.closeEntry();
                    inputStream.close();
                } else {
                    log.error("文件下载失败,响应码:" + responseCode + ",URL:" + fileURL);
                    continue;
                }
            } catch (Exception e) {
                log.error("下载或压缩文件失败: " + fileURL, e);
                continue;
            }
        }
    } catch (Exception e) {
        log.error("下载或压缩文件失败", e);
    }

    return outputStream;
}

前端代码

import { saveAs } from 'file-saver'
export default {
	zip(url, name) {
		var url = baseURL + url
		downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
		axios({
		  method: 'get',
		  url: url,
		  responseType: 'blob',
		  headers: { 'Authorization': 'Bearer ' + getToken() }
		}).then((res) => {
		  const isBlob = blobValidate(res.data);
		  if (isBlob) {
		    const blob = new Blob([res.data], { type: 'application/zip' })
		    this.saveAs(blob, name)
		  } else {
		    this.printErrMsg(res.data);
		  }
		  downloadLoadingInstance.close();
		}).catch((r) => {
		  console.error(r)
		  Message.error('下载文件出现错误,请联系管理员!')
		  downloadLoadingInstance.close();
		})
	},
	blobValidate(data) {
	 	return data.type !== 'application/json'
	},
	saveAs(text, name, opts) {
	  saveAs(text, name, opts);
	},
	async printErrMsg(data) {
	    const resText = await data.text();
	    const rspObj = JSON.parse(resText);
	    const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
	    Message.error(errMsg);
  }
}

调用

downloadContractFile(row) {
  this.$download.zip("/contract/contract/downloadContractFile/" + row.contractId,  `合同档案_${new Date().getTime()}`)
},
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值