批量下载
    适用场景

    1. @RestController
    2. @Api(tags = "ExportController")
    3. @RequestMapping("/export")
    4. @Validated
    5. @AllArgsConstructor
    6. @Slf4j
    7. public class ExportController {
    8. private final ArchivalFileMapService archivalFileMapService;
    9. private final ExportService exportService;
    10. private final DataService dataService;
    11. /**
    12. * 按档号导出,以档号为文件夹名称
    13. * <br/>
    14. *
    15. * @param archivalCode
    16. * @param httpResponse
    17. * @return com.hzzl.erms.archival.common.api.CommonResult<?>
    18. */
    19. @ApiOperation(value = "按档号导出文件")
    20. @RequestMapping(value = "/archival", method = RequestMethod.GET)
    21. @SneakyThrows
    22. public void exportInfoAuto(@RequestParam @NotBlank String archivalCode, HttpServletResponse httpResponse) {
    23. log.info("exportInfoAuto() called with parameters => 【archivalCode = {}】", archivalCode);
    24. // 查询档号对应的文件列表
    25. List<ArchivalFileMap> archivalFileMaps = archivalFileMapService.selectByArchivalCode(archivalCode);
    26. Assert.notEmpty(archivalFileMaps);
    27. //生成Excel文件 archivalTmp
    28. String excelPath =
    29. StrUtil.builder().append(PathUtil.excelPath()).append(archivalCode).append(".xlsx").toString();
    30. File excel = FileUtil.newFile(excelPath);
    31. //待导出的条目数据
    32. List<ExportEntity> list = new ArrayList<>();
    33. list = generateMockData();
    34. exportService.exportList(list, includedColumnFields(), excelPath);
    35. // 用于存储所有需要下载的文件
    36. List<SysFile> listFile =
    37. archivalFileMaps.stream().map(a -> {
    38. SysFile fileInfo = archivalFileMapService.getFileInfo(a.getUuid());
    39. Assert.notNull(fileInfo);
    40. return fileInfo;
    41. }).collect(Collectors.toList());
    42. // 以当前日期作为 zip 压缩包的名称
    43. String zipName = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()) + ".zip";
    44. // 清空输出流
    45. httpResponse.reset();
    46. httpResponse.setCharacterEncoding("UTF-8");
    47. // 注意写法,避免中文乱码
    48. httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));
    49. httpResponse.setContentType("application/x-msdownload");
    50. @Cleanup
    51. BufferedOutputStream bos = null;
    52. bos = new BufferedOutputStream(httpResponse.getOutputStream());
    53. @Cleanup
    54. ZipOutputStream out = new ZipOutputStream(bos);
    55. //把Excel放入压缩包
    56. ZipEntry excelEntry = new ZipEntry(excel.getName());
    57. out.putNextEntry(excelEntry);
    58. out.write(FileUtil.readBytes(excel));
    59. Assert.notEmpty(listFile);
    60. for (SysFile sysFile : listFile) {
    61. Assert.notNull(sysFile.getUrl());
    62. // 对url进行预处理后,使用 Hutool 工具类下载
    63. HttpResponse res = HttpRequest.get(UrlEncodeUtil.reformatUrl(sysFile.getUrl())).execute();
    64. InputStream object = res.bodyStream();
    65. byte[] buf = new byte[1024];
    66. int length = 0;
    67. String strDirectoryLevel =
    68. StrUtil.builder()
    69. .append(archivalCode)
    70. .append(PathUtil.separator())
    71. .append(sysFile.getName())
    72. .toString();
    73. final ZipEntry zipEntry = new ZipEntry(strDirectoryLevel);
    74. out.putNextEntry(zipEntry);
    75. while ((length = object.read(buf)) > 0) {
    76. out.write(buf, 0, length);
    77. }
    78. }
    79. out.close();
    80. bos.close();
    81. FileUtil.del(excel);
    82. }
    83. }
    1. public class UrlEncodeUtil {
    2. // 防止url中有中文出现异常
    3. @SneakyThrows
    4. public static String reformatUrl(String url) {
    5. List<String> list = StrUtil.split(url, "/");
    6. String tmp = list.get(list.size() - 1);
    7. URLEncoder.encode(tmp, "UTF-8");
    8. String urlTmp = StrUtil.subBefore(url, "/", true).toString() + "/" + tmp;
    9. url = StrUtil.builder().append(urlTmp).toString();
    10. return url;
    11. }
    12. }

    重构一下

    1. @ApiOperation(value = "按档号导出文件")
    2. @RequestMapping(value = "/archival", method = RequestMethod.GET)
    3. @SneakyThrows
    4. public void exportInfoAuto(@RequestParam @NotBlank String archivalCode, HttpServletResponse httpResponse) {
    5. log.info("exportInfoAuto() called with parameters => 【archivalCode = {}】", archivalCode);
    6. // 查询档号对应的文件列表
    7. List<ArchivalFileMap> archivalFileMaps = archivalFileMapService.selectByArchivalCode(archivalCode);
    8. Assert.notEmpty(archivalFileMaps);
    9. //生成Excel文件 archivalTmp
    10. String excelPath =
    11. StrUtil.builder().append(PathUtil.excelPath()).append(archivalCode).append(".xlsx").toString();
    12. File excel = FileUtil.newFile(excelPath);
    13. //待导出的条目数据
    14. List<ExportEntity> list = new ArrayList<>();
    15. list = generateMockData();
    16. exportService.exportList(list, includedColumnFields(), excelPath);
    17. // 用于存储所有需要下载的文件
    18. List<SysFile> listFile =
    19. archivalFileMaps.stream().map(a -> {
    20. SysFile fileInfo = archivalFileMapService.getFileInfo(a.getUuid());
    21. Assert.notNull(fileInfo);
    22. return fileInfo;
    23. }).collect(Collectors.toList());
    24. // 以当前日期作为 zip 压缩包的名称
    25. String zipName = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()) + ".zip";
    26. // 设置返回信息的元信息
    27. setResponseHeaderMeta(httpResponse, zipName);
    28. @Cleanup
    29. BufferedOutputStream bos = null;
    30. bos = new BufferedOutputStream(httpResponse.getOutputStream());
    31. @Cleanup
    32. ZipOutputStream out = new ZipOutputStream(bos);
    33. //把Excel放入压缩包
    34. ZipEntry excelEntry = new ZipEntry(excel.getName());
    35. out.putNextEntry(excelEntry);
    36. out.write(FileUtil.readBytes(excel));
    37. Assert.notEmpty(listFile);
    38. for (SysFile sysFile : listFile) {
    39. Assert.notNull(sysFile.getUrl());
    40. //构造目录层级
    41. String strDirectoryLevel =
    42. StrUtil.builder()
    43. .append(archivalCode)
    44. .append(PathUtil.separator())
    45. .append(sysFile.getName())
    46. .toString();
    47. final ZipEntry zipEntry = new ZipEntry(strDirectoryLevel);
    48. out.putNextEntry(zipEntry);
    49. // 对url进行预处理后,使用 Hutool 工具类下载
    50. out.write(HttpUtil.downloadBytes(UrlEncodeUtil.reformatUrl(sysFile.getUrl())));
    51. }
    52. out.close();
    53. bos.close();
    54. FileUtil.del(excel);
    55. }
    56. @SneakyThrows
    57. private void setResponseHeaderMeta(HttpServletResponse httpResponse, String fileName) {
    58. // 清空输出流
    59. httpResponse.reset();
    60. httpResponse.setCharacterEncoding("UTF-8");
    61. // 注意写法,避免中文乱码
    62. httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    63. httpResponse.setContentType("application/x-msdownload");
    64. }