项目场景:
vue+srpingboot实现多文件导出
解决方案:
直接上干货
<el-button type="warning" icon="el-icon-download" size="mini" class="no-margin" @click="exportSelectedFiles" :disabled="selectedRows.length === 0">导出</el-button>
async exportSelectedFiles() {
if (this.selectedRows.length === 0) {
this.$message.warning('请至少选择一条记录');
return;
}
// 提取所有选中的文件的 id
const fileIds = this.selectedRows.map(row => row.id);
// 请求文件路径数据
const params = { id: fileIds };
const fileResponse = await url.getFilePatchData(params);
if (fileResponse.data && fileResponse.data.length > 0) {
// 提取文件路径
const filePaths = fileResponse.data.map(file => file.filepath);
this.downloadMultipleFiles(filePaths);
} else {
this.$message.error('无法获取文件路径');
}
},
const fileResponse = await url.getFilePatchData(params);这行代码其实就是一个查询接口
选择这条数据将他下面所属的文档路径查询出来 然后调用下载文档的方法
// 下载多个文件(打包为ZIP)
downloadMultipleFiles(filePaths) {
const params = { filePaths: filePaths };
url.downloadMultiple(params)
.then(response => {
// 关键修复:确保正确解析二进制流
const blob = new Blob([response], { type: 'application/zip' });
if (blob.size === 0) {
this.$message.error('服务器返回空文件');
return;
}
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = `documents_${Date.now()}.zip`;
document.body.appendChild(link);
link.click();
// 延迟清理以避免下载中断
setTimeout(() => {
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
}, 200);
})
.catch(error => {
this.$message.error('文件下载失败: ' + error.message);
});
},
url.downloadMultiple(params)也是调用的后端接口跟this.axios=url一样
//多条导出zip
@PostMapping("/download-multiple")
public void downloadMultipleFiles(@RequestBody Map<String, List<String>> requestBody,
HttpServletResponse response) throws IOException {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=documents.zip");
response.resetBuffer();
try (ZipOutputStream zipOut = new ZipOutputStream(
new BufferedOutputStream(response.getOutputStream()))) {
byte[] buffer = new byte[8192];
for (String filePath : requestBody.get("filePaths")) {
Path file = Paths.get(filePath).normalize();
if (!Files.exists(file) || Files.isDirectory(file)) continue;
try (InputStream in = new BufferedInputStream(Files.newInputStream(file))) {
ZipEntry entry = new ZipEntry(file.getFileName().toString());
zipOut.putNextEntry(entry);
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
zipOut.write(buffer, 0, bytesRead);
}
zipOut.closeEntry();
zipOut.flush();
}
}
}
}
调用zip的插件导入对应的依赖即可实现多文件导出,导出会保存生成zip压缩包