SpringBoot中使用EasyExcel并行导出多个excel文件并压缩zip后下载

❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基

背景

SpringBoot的同步导出方式中,服务器会阻塞直到Excel文件生成完毕,在处理大量数据的导出功能,利用CompletableFuture,我们可以将导出任务异步化,最后 这些文件进一步压缩成ZIP格式以方便下载:

DEMO代码:

@RestController
@RequestMapping("/export")
public class ExportController {
    
    

    @Autowired
    private 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";

    @Autowired
    private 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);
    }
}

关注公众号[码到三十五]获取更多技术干货 !

猜你喜欢

转载自blog.csdn.net/qq_26664043/article/details/142287898