1. 项目依赖
首先,我们需要引入相关的依赖,包括 Spring Boot 和阿里巴巴的 EasyExcel 组件,此外还需要使用 Java 的 Zip 工具进行压缩操作。
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<!-- Commons IO(用于压缩文件操作) -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
2. 创建数据导出逻辑
接下来,我们定义数据导出逻辑。在这个例子中,假设我们有一个订单表,我们将导出每个用户的订单信息到不同的 Excel 文件中。
2.1 定义数据模型
public class Order {
private Long id;
private String productName;
private Integer quantity;
private BigDecimal price;
// Getters and Setters
}
2.2 使用 EasyExcel 导出 Excel 文件
EasyExcel 的 API 使用非常简单,下面是一个基本的写 Excel 文件的例子。我们使用 ExcelWriterBuilder 来创建 Excel,并写入数据。
import com.alibaba.excel.EasyExcel;
import java.io.File;
import java.util.List;
public class ExcelExportUtil {
public static void writeOrdersToExcel(List<Order> orders, String filePath) {
EasyExcel.write(filePath, Order.class)
.sheet("订单数据")
.doWrite(orders);
}
}
2.3 并行导出多个 Excel 文件
为了提高效率,我们可以使用 Java 的 CompletableFuture 实现并行导出。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExportService {
private final ExecutorService executor = Executors.newFixedThreadPool(10); // 自定义线程池
public void exportOrdersInParallel(List<List<Order>> ordersList, String outputDir) {
CompletableFuture[] futures = ordersList.stream()
.map(orders -> CompletableFuture.runAsync(() -> {
String fileName = "订单_" + Thread.currentThread().getId() + ".xlsx";
ExcelExportUtil.writeOrdersToExcel(orders, outputDir + fileName);
}, executor))
.toArray(CompletableFuture[]::new);
// 等待所有任务完成
CompletableFuture.allOf(futures).join();
}
}
ordersList 是一个包含多个用户订单的列表,每个列表中的订单将导出到一个 Excel 文件。通过使用并行处理,可以同时生成多个文件。
3. 压缩文件为 zip
完成 Excel 文件的导出后,我们需要将这些文件压缩成一个 zip 文件。
3.1 使用 ZipOutputStream 进行压缩
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipUtil {
public static void zipFiles(String sourceDir, String zipFile) throws IOException {
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zipOut = new ZipOutputStream(fos);
File fileToZip = new File(sourceDir);
for (File file : fileToZip.listFiles()) {
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
zipOut.close();
fos.close();
}
}
在这个方法中,我们遍历指定文件夹中的所有文件,并将它们写入到 zip 文件中。
4. 实现下载功能
在 Spring Boot 中,可以通过 HTTP 响应的形式将生成的 zip 文件提供给前端下载。
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.*;
@RestController
public class FileDownloadController {
@GetMapping("/downloadZip")
public ResponseEntity<InputStreamResource> downloadZip() throws IOException {
String zipFilePath = "/tmp/orders.zip";
ZipUtil.zipFiles("/tmp/excel_files", zipFilePath);
File file = new File(zipFilePath);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.contentLength(file.length())
.body(resource);
}
}
通过这个接口,前端用户可以通过点击下载链接,直接获取到压缩好的 Excel 文件包。
5. 完整的业务流程
-
数据分批处理:假设我们要导出上百万条订单数据,首先需要根据用户或其他条件将数据进行分片,每片数据导出到不同的 Excel 文件。
-
并行处理:使用 CompletableFuture 并行处理各个数据片段,确保多个 Excel 文件同时生成,以加快处理速度。
-
文件压缩:所有 Excel 文件生成后,通过 ZipOutputStream 将其压缩为一个 zip 文件。
-
提供下载:用户通过前端的下载链接,能够方便地获取压缩包。
6. 总结
本文详细介绍了如何使用 Spring Boot 和 EasyExcel 实现大规模数据的高效导出,并通过并行处理与 zip 压缩优化用户体验。这种方案特别适合需要处理大量数据导出的企业系统,在提升效率的同时,保证了系统的稳定性和可扩展性。