实现批量下载,文件按照类别放到不同文件夹,并生成压缩包
实现思路
- 获取所有文件信息(类别、名称、文件路径等)
- 对获取的文件List进行分组,根据某个维度进行分组,可以使用 Collectors.groupingBy(XXX::getXx) 的方式分组得到Map<String, List>
- 创建 ZipOutputStream 对象
- 在ZipOutputStream 中,根据步骤2中的Map<String, List>将List中的文件通过文件流将文件输入到zip中
- 得到对应的zip压缩文件,再将压缩文件zip发送给前端
- 关闭流
代码实现
public void batchDownload(@RequestBody List<UploadInfoDto> uploadInfoListDto, HttpServletResponse response) throws Exception {
List<UploadInfo> uploadInfos = new ArrayList<>();
for (UploadInfoDto dto : uploadInfoListDto) {
List<UploadInfo> currentUploadInfos = uploadService.getUploadFile(dto);
uploadInfos.addAll(currentUploadInfos);
}
String zipName = "annex.zip";
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zipName, "UTF-8"));
logger.info("开始下载");
Map<String, List<UploadInfo>> UploadInfoGroup = uploadInfos.stream().collect(Collectors.groupingBy(UploadInfo::getClaimNo));
String zipFilePath = "billFileAnnex.zip";
OutputStream os = response.getOutputStream();
try {
FileOutputStream fos = new FileOutputStream(zipFilePath);
ZipOutputStream zos = new ZipOutputStream(fos);
for (String category : UploadInfoGroup.keySet()) {
ZipEntry entry = new ZipEntry(category + "/");
zos.putNextEntry(entry);
for (UploadInfo uploadInfo : UploadInfoGroup.get(claimNo)) {
Map<String, Object> metaMap = new HashMap<>();
InputStream is = OSSUtil.downloadObject(uploadInfo.getFilePath());
addFileToZip(zos, uploadInfo, is);
}
}
zos.flush();
zos.close();
BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get(zipFilePath)));
byte[] buffer = new byte[1024];
int length;
while ((length = bis.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
bis.close();
os.flush();
os.close();
logger.info("压缩完成!");
File zipFile = new File(zipFilePath);
if (zipFile.delete()) {
logger.info("delete file success");
}
} catch (IOException e) {
logger.error("批量文件下载异常");
e.printStackTrace();
}
}
private static void addFileToZip(ZipOutputStream zos, UploadInfo uploadInfo, InputStream inputStream) throws IOException {
ZipEntry entry = new ZipEntry(uploadInfo.getCategory() + "/" + uploadInfo.getFileName());
zos.putNextEntry(entry);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
inputStream.close();
}
效果截图
