今天做需求突然看到之前产品提的需求,导出多个文件为压缩包。功能部分早就已经完成了,想到还没有过类似的记录,今天就记录下来吧,是记录也是学历,如果有不对的地方还请多多指教。以下贴出的代码是下载压缩包的源代码,我的文件资源是存储在服务器根目录下,表中记录的文件存储的绝对路径,通过路径反查获取资源下载,看官可根据自己项目的情况判断是否适用你当下的需求场景。废话不多说,直接上代码:
controller层:
/**
* 下载压缩包
* @param request
* @param response
* @param idDTO 传入文件id
*/
@SneakyThrows
@PostMapping("/download-zip")
@ApiOperation(value = "下载文件为压缩包")
public SwaggerAjaxResult downloadFileZip(HttpServletRequest request, HttpServletResponse response, @RequestBody @Valid UpdateFileDTO idDTO){
return SwaggerAjaxResult.success(inspectionProblemService.downloadFileZip(request,response,idDTO.getId()));
}
service 层代码:
/**
* 下载文件为压缩包
*
* @param request
* @param response
* @param id
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SwaggerAjaxResult downloadFileZip(HttpServletRequest request, HttpServletResponse response, String id) {
try {
List<TFile> fileVOList = fileService.lambdaQuery()
.eq(TFile::getParentId, id)
.eq(TFile::getParentTable, PROBLEM_TABLE_NAME)
.eq(TFile::getType, WJXX)
.list();
Assert.notNull(fileVOList, "文件为空!");
String fileName = super.baseMapper.getFileName(id);
Assert.notNull(fileName, "文件名不能为空!");
//创建临时路径,存放压缩文件
String zipFilePath = System.getProperty("user.dir") + File.separator + "downloadZip" + File.separator;
log.info("文件临时路径为:{}", zipFilePath);
//如果文件不存在创创建新文件
File zipFile = new File(zipFilePath);
if (!zipFile.exists()) {
zipFile.mkdirs();
}
//在临时文件夹里创建临时文件
String temporaryZipName = zipFilePath + "临时存放.zip";
//如果不存在就新创建一个
File zipFiles = new File(temporaryZipName);
if (!zipFiles.exists()) {
zipFiles.createNewFile();
}
//压缩输出流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(temporaryZipName));
//将文件写入压缩包
for (TFile file : fileVOList) {
writingFilesToZip(zipFilePath, zipOut, file, request);
}
//压缩完成关闭压缩流
zipOut.close();
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8") + ".zip");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
ServletOutputStream outputStream = response.getOutputStream();
FileInputStream inputStream = new FileInputStream(temporaryZipName);
IOUtils.copy(inputStream, outputStream);
//关闭输入流
inputStream.close();
//下载完成,删除临时文件
File file = new File(zipFilePath);
FileUtils.deleteFile(file);
log.info("下载zip成功!");
return SwaggerAjaxResult.success("下载zip成功!");
} catch (IOException e) {
e.printStackTrace();
log.warn("下载zip失败!{}", e.getMessage());
return SwaggerAjaxResult.error("下载zip失败!{}", e.getMessage());
}
}
/**
* @param zipFilePath
* @param zipOut
* @param fileVO
*/
private void writingFilesToZip(String zipFilePath, ZipOutputStream zipOut, TFile fileVO, HttpServletRequest request) throws IOException {
String savePath = fileVO.getFileLink();
//通过URL将文件下载至本地
downLoadFromUrl(savePath, zipFilePath, fileVO.getFileName(), request);
byte[] buf = new byte[2 * 1024];
String srcDir = zipFilePath + fileVO.getFileName();
File sourceFile = new File(srcDir);
zipOut.putNextEntry(new ZipEntry(fileVO.getFileName()));
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zipOut.write(buf, 0, len);
}
zipOut.closeEntry();
in.close();
}
private void downLoadFromUrl(String savePath, String zipFilePath, String fileName, HttpServletRequest request) throws IOException {
File file1 = new File(savePath);
byte[] getData = new byte[0];
try {
getData = org.apache.commons.io.FileUtils.readFileToByteArray(file1);
} catch (IOException e) {
log.warn("文件:{}不能访问!", savePath);
}
//文件保存位置
File saveDir = new File(zipFilePath);
if (!saveDir.exists()) {
saveDir.mkdir();
}
File file = new File(saveDir + File.separator + fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(getData);
fos.close();
}
– 2024-02-22更新
用java包里面的方法导出压缩包
//导出压缩包文件名称
response.setHeader("Content-disposition", "attachment;filename="
+ DateUtil.parseDate(reqParam.getStartTime()).toString(DatePattern.PURE_DATE_PATTERN) + "-"
+ DateUtil.parseDate(reqParam.getEndTime()).toString(DatePattern.PURE_DATE_PATTERN)
+ URLEncoder.encode("xxxx管理信息", "UTF-8") + ".zip");
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
//groupByDate为将要导出的文件数据,我这里是按照数据的日期分组了,按日期数据为一个excel导出,最后组成一个压缩包
try {
for (Map.Entry<String, List<GrainReserveInfoVO>> entry : groupByDate.entrySet()) {
String key = entry.getKey();
AtomicInteger serialNo = new AtomicInteger(1);
entry.getValue().forEach(temp -> temp.setSerialNo(serialNo.getAndIncrement()));
ExcelWriter excelWriter = EasyExcel.write()
.excelType(ExcelTypeEnum.XLSX)
.autoCloseStream(Boolean.FALSE)
.registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, bodyStyle))
.build();
WriteSheet writeSheet = EasyExcel.writerSheet(key.substring(5, 7) + "月" + key.substring(8) + "日").build();
WriteTable writeTable = EasyExcel.writerTable(0).head(GrainReserveInfoVO.class).needHead(Boolean.TRUE).build();
excelWriter.write(entry.getValue(), writeSheet, writeTable);
//压缩包里每一个文件名称设置
ZipEntry zipEntry = new ZipEntry(DateUtil.parseDate(key).toString(DatePattern.PURE_DATE_PATTERN) + "xxxx管理信息.xlsx");
zipOutputStream.putNextEntry(zipEntry);
Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
workbook.write(zipOutputStream);
}
zipOutputStream.flush();
} catch (Exception e) {
log.error("导出xxxx失败", e);
throw new CustomException("导出xxxx异常");
} finally {
//关闭数据流,注意关闭的顺序
zipOutputStream.close();
outputStream.close();
}
如有不足,请多多指教!