批量下载
适用场景
@RestController@Api(tags = "ExportController")@RequestMapping("/export")@Validated@AllArgsConstructor@Slf4jpublic class ExportController {private final ArchivalFileMapService archivalFileMapService;private final ExportService exportService;private final DataService dataService;/*** 按档号导出,以档号为文件夹名称* <br/>** @param archivalCode* @param httpResponse* @return com.hzzl.erms.archival.common.api.CommonResult<?>*/@ApiOperation(value = "按档号导出文件")@RequestMapping(value = "/archival", method = RequestMethod.GET)@SneakyThrowspublic void exportInfoAuto(@RequestParam @NotBlank String archivalCode, HttpServletResponse httpResponse) {log.info("exportInfoAuto() called with parameters => 【archivalCode = {}】", archivalCode);// 查询档号对应的文件列表List<ArchivalFileMap> archivalFileMaps = archivalFileMapService.selectByArchivalCode(archivalCode);Assert.notEmpty(archivalFileMaps);//生成Excel文件 archivalTmpString excelPath =StrUtil.builder().append(PathUtil.excelPath()).append(archivalCode).append(".xlsx").toString();File excel = FileUtil.newFile(excelPath);//待导出的条目数据List<ExportEntity> list = new ArrayList<>();list = generateMockData();exportService.exportList(list, includedColumnFields(), excelPath);// 用于存储所有需要下载的文件List<SysFile> listFile =archivalFileMaps.stream().map(a -> {SysFile fileInfo = archivalFileMapService.getFileInfo(a.getUuid());Assert.notNull(fileInfo);return fileInfo;}).collect(Collectors.toList());// 以当前日期作为 zip 压缩包的名称String zipName = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()) + ".zip";// 清空输出流httpResponse.reset();httpResponse.setCharacterEncoding("UTF-8");// 注意写法,避免中文乱码httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));httpResponse.setContentType("application/x-msdownload");@CleanupBufferedOutputStream bos = null;bos = new BufferedOutputStream(httpResponse.getOutputStream());@CleanupZipOutputStream out = new ZipOutputStream(bos);//把Excel放入压缩包ZipEntry excelEntry = new ZipEntry(excel.getName());out.putNextEntry(excelEntry);out.write(FileUtil.readBytes(excel));Assert.notEmpty(listFile);for (SysFile sysFile : listFile) {Assert.notNull(sysFile.getUrl());// 对url进行预处理后,使用 Hutool 工具类下载HttpResponse res = HttpRequest.get(UrlEncodeUtil.reformatUrl(sysFile.getUrl())).execute();InputStream object = res.bodyStream();byte[] buf = new byte[1024];int length = 0;String strDirectoryLevel =StrUtil.builder().append(archivalCode).append(PathUtil.separator()).append(sysFile.getName()).toString();final ZipEntry zipEntry = new ZipEntry(strDirectoryLevel);out.putNextEntry(zipEntry);while ((length = object.read(buf)) > 0) {out.write(buf, 0, length);}}out.close();bos.close();FileUtil.del(excel);}}
public class UrlEncodeUtil {// 防止url中有中文出现异常@SneakyThrowspublic static String reformatUrl(String url) {List<String> list = StrUtil.split(url, "/");String tmp = list.get(list.size() - 1);URLEncoder.encode(tmp, "UTF-8");String urlTmp = StrUtil.subBefore(url, "/", true).toString() + "/" + tmp;url = StrUtil.builder().append(urlTmp).toString();return url;}}
重构一下
@ApiOperation(value = "按档号导出文件")@RequestMapping(value = "/archival", method = RequestMethod.GET)@SneakyThrowspublic void exportInfoAuto(@RequestParam @NotBlank String archivalCode, HttpServletResponse httpResponse) {log.info("exportInfoAuto() called with parameters => 【archivalCode = {}】", archivalCode);// 查询档号对应的文件列表List<ArchivalFileMap> archivalFileMaps = archivalFileMapService.selectByArchivalCode(archivalCode);Assert.notEmpty(archivalFileMaps);//生成Excel文件 archivalTmpString excelPath =StrUtil.builder().append(PathUtil.excelPath()).append(archivalCode).append(".xlsx").toString();File excel = FileUtil.newFile(excelPath);//待导出的条目数据List<ExportEntity> list = new ArrayList<>();list = generateMockData();exportService.exportList(list, includedColumnFields(), excelPath);// 用于存储所有需要下载的文件List<SysFile> listFile =archivalFileMaps.stream().map(a -> {SysFile fileInfo = archivalFileMapService.getFileInfo(a.getUuid());Assert.notNull(fileInfo);return fileInfo;}).collect(Collectors.toList());// 以当前日期作为 zip 压缩包的名称String zipName = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()) + ".zip";// 设置返回信息的元信息setResponseHeaderMeta(httpResponse, zipName);@CleanupBufferedOutputStream bos = null;bos = new BufferedOutputStream(httpResponse.getOutputStream());@CleanupZipOutputStream out = new ZipOutputStream(bos);//把Excel放入压缩包ZipEntry excelEntry = new ZipEntry(excel.getName());out.putNextEntry(excelEntry);out.write(FileUtil.readBytes(excel));Assert.notEmpty(listFile);for (SysFile sysFile : listFile) {Assert.notNull(sysFile.getUrl());//构造目录层级String strDirectoryLevel =StrUtil.builder().append(archivalCode).append(PathUtil.separator()).append(sysFile.getName()).toString();final ZipEntry zipEntry = new ZipEntry(strDirectoryLevel);out.putNextEntry(zipEntry);// 对url进行预处理后,使用 Hutool 工具类下载out.write(HttpUtil.downloadBytes(UrlEncodeUtil.reformatUrl(sysFile.getUrl())));}out.close();bos.close();FileUtil.del(excel);}@SneakyThrowsprivate void setResponseHeaderMeta(HttpServletResponse httpResponse, String fileName) {// 清空输出流httpResponse.reset();httpResponse.setCharacterEncoding("UTF-8");// 注意写法,避免中文乱码httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));httpResponse.setContentType("application/x-msdownload");}
