SpringBoot中使用EasyExcel并行导出多个excel文件并压缩zip后下载
❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基
背景
SpringBoot的同步导出方式中,服务器会阻塞直到Excel文件生成完毕,在处理大量数据的导出功能,利用CompletableFuture,我们可以将导出任务异步化,最后 这些文件进一步压缩成ZIP格式以方便下载:
DEMO代码:
@RestController
@RequestMapping("/export")
public class ExportController {@Autowiredprivate ExcelExportService excelExportService;@GetMapping("/zip")public ResponseEntity<byte[]> exportToZip() throws Exception {List<List<Data>> dataSets = multipleDataSets();List<CompletableFuture<String>> futures = new ArrayList<>();// 异步导出所有Excel文件String outputDir = "path/to/output/dir/";for (List<Data> dataSet : dataSets) {futures.add(excelExportService.exportDataToExcel(dataSet, outputDir));}// 等待所有导出任务完成 CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).get(10, TimeUnit.MINUTES);;// 收集Excel文件路径List<String> excelFilePaths = futures.stream().map(CompletableFuture::join) // 获取文件路径.collect(Collectors.toList());// 压缩文件File zipFile = new File("path/to/output.zip");try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile))) {for (String filePath : excelFilePaths) {zipFile(new File(filePath), zipOut, new File(filePath).getName());}}// 返回ZIP文件byte[] data = Files.readAllBytes(zipFile.toPath());return ResponseEntity.ok().header("Content-Disposition", "attachment; filename=\"" + zipFile.getName() + "\"").contentType(MediaType.parseMediaType("application/zip")).body(data);}// 将文件添加到ZIP输出流中 private void zipFile(File file, ZipOutputStream zipOut, String entryName) throws IOException { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) { ZipEntry zipEntry = new ZipEntry(entryName); zipOut.putNextEntry(zipEntry); byte[] bytesIn = new byte[4096]; int read; while ((read = bis.read(bytesIn)) != -1) { zipOut.write(bytesIn, 0, read); } zipOut.closeEntry(); } } // 获取数据private List<List<Data>> multipleDataSets() {}
}
SpringBoot异步并行生成excel文件,利用EasyExcel
库来简化Excel的生成过程:
@Service
public class ExcelExportService {private static final String TEMPLATE_PATH = "path/to/template.xlsx";@Autowiredprivate TaskExecutor taskExecutor; public CompletableFuture<Void> exportDataToExcel(List<Data> dataList, String outputDir) {Path temproaryFilePath = Files.createTempFile(outputDir, "excelFilePre",".xlsx");return CompletableFuture.runAsync(() -> {try (OutputStream outputStream = new FileOutputStream(temproaryFilePath )) {EasyExcel.write(outputStream, Data.class).withTemplate(TEMPLATE_PATH).sheet().doFill(dataList).finish();return temproaryFilePath.toString();} catch (IOException e) {throw new RuntimeException("Failed to export Excel file", e);}}, taskExecutor);}
}