个人笔记,欢迎指正
后端代码
// 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()}`)
},
1万+

被折叠的 条评论
为什么被折叠?



