批量下载大致思路是:
前端将要下载的文件的信息通过多选,传递到后端,后端我们通过附件的信息去查询到文件所在nas(专用数据存储服务器)路径,然后遍历要下载的文件列表,逐个放入压缩包中,返回给前端。
/*
*这是后端实现代码
*/
@SneakyThrows
public void downloadBatch(HttpServletRequest request, HttpServletResponse response, List<String> urls){
// 文件下载路径
List<String> filePaths = new ArrayList<>();
//服务器文件所在路径
String pathName = filePath;
//解析传来的url路径
urls.stream().forEach(
url -> {
String filePath = datePath + "/" + fileName;
if(filePath.contains("../")||filePath.contains("%")||filePath.contains("./")) throw new ServiceException("文件包含非法字符");
filePaths.add(pathName+filePath);
}
);
log.info("批量下载路径解析完毕");
String zipFileName = "files.zip"; // 修改为你需要的zip文件名
createZipFile(filePaths, zipFileName);
serveFile(request, response, zipFileName);
}
public void createZipFile(List<String> filePaths, String zipFileName) throws IOException {
FileOutputStream fos = new FileOutputStream(zipFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
for (String filePath : filePaths) {
addToZipFile(filePath, zos);
}
zos.close();
fos.close();
}
private void addToZipFile(String filePath, ZipOutputStream zos) throws IOException {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
}
private void serveFile(HttpServletRequest request, HttpServletResponse response, String filename) throws IOException {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename=" + filename);
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int length;
OutputStream outputStream = response.getOutputStream();
while ((length = fis.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
fis.close();
outputStream.flush();
outputStream.close();
}
前端代码
request(`url`, {
method: 'post',
params: params,
responseType: 'blob',
headers: {
'Sino-Auth': `${getToken()}`,
},
})
.then((response) => {
// 获取到文件流数据
console.log('进入',response)
const blobUrl = window.URL.createObjectURL(response);
const aElement = document.createElement('a');
const root = document.getElementById('root');
const filename = fileName ? fileName : '附件.zip'; // 设置文件名称
aElement.href = blobUrl; // 设置a标签路径
aElement.download = filename;
root?.append(aElement);
aElement.click();
window.URL.revokeObjectURL(blobUrl);
aElement.remove();
console.log('下载',response)
}
) .catch((error) => {
message.error('文件下载失败')
console.log('文件下载失败', error);
});