案例一
java
复制代码
@RestController
@RequestMapping("/export")
public class ExportController {
private final ExecutorService executor = Executors.newFixedThreadPool(5);
@GetMapping("/multiSheet")
public void exportMultiSheet(HttpServletResponse response) throws Exception {
// 构造5个CompletableFuture,每个处理自己的表和业务逻辑
CompletableFuture<SheetData> future1 = CompletableFuture.supplyAsync(() -> handleUsers(), executor);
CompletableFuture<SheetData> future2 = CompletableFuture.supplyAsync(() -> handleOrders(), executor);
CompletableFuture<SheetData> future3 = CompletableFuture.supplyAsync(() -> handleProducts(), executor);
CompletableFuture<SheetData> future4 = CompletableFuture.supplyAsync(() -> handleLogs(), executor);
CompletableFuture<SheetData> future5 = CompletableFuture.supplyAsync(() -> handleCustomers(), executor);
// 等待所有处理完成
CompletableFuture<Void> allDone = CompletableFuture.allOf(future1, future2, future3, future4, future5);
allDone.thenRun(() -> {
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("multi_sheet_export", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
// 依次写入每个Sheet(join获取数据)
List<CompletableFuture<SheetData>> futures = Arrays.asList(future1, future2, future3, future4, future5);
for (int i = 0; i < futures.size(); i++) {
SheetData data = futures.get(i).join();
WriteSheet sheet = EasyExcel.writerSheet(i, data.getSheetName())
.head(data.getHead())
.build();
excelWriter.write(data.getRows(), sheet);
}
excelWriter.finish();
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown(); // 一定要关闭线程池
}
}).join(); // 等待导出完成
}
// 示例方法,每个表处理逻辑不同
private SheetData handleUsers() {
// 查询 users 表,并处理逻辑(脱敏、计算、筛选等)
return queryAndBuildSheet("users", "用户信息");
}
private SheetData handleOrders() {
// 查询 orders 表,自定义业务逻辑处理
return queryAndBuildSheet("orders", "订单信息");
}
private SheetData handleProducts() {
return queryAndBuildSheet("products", "商品列表");
}
private SheetData handleLogs() {
return queryAndBuildSheet("logs", "操作日志");
}
private SheetData handleCustomers() {
return queryAndBuildSheet("customers", "客户信息");
}
// 通用方法:查询数据库并生成 SheetData
private SheetData queryAndBuildSheet(String tableName, String sheetName) {
List<List<String>> headers = new ArrayList<>();
List<List<String>> rows = new ArrayList<>();
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_db", "user", "password");
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + tableName);
ResultSet rs = stmt.executeQuery()) {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
List<String> headerRow = new ArrayList<>();
for (int i = 1; i <= columnCount; i++) {
headerRow.add(meta.getColumnLabel(i));
}
headers.add(headerRow);
while (rs.next()) {
List<String> row = new ArrayList<>();
for (int i = 1; i <= columnCount; i++) {
Object val = rs.getObject(i);
// 可以在这里做字段处理,比如脱敏、格式转换等
row.add(val != null ? val.toString() : "");
}
rows.add(row);
}
} catch (SQLException e) {
e.printStackTrace();
}
return new SheetData(sheetName, headers, rows);
}
// SheetData结构,用于封装每个 Sheet 页的数据
static class SheetData {
private final String sheetName;
private final List<List<String>> head;
private final List<List<String>> rows;
public SheetData(String sheetName, List<List<String>> head, List<List<String>> rows) {
this.sheetName = sheetName;
this.head = head;
this.rows = rows;
}
public String getSheetName() { return sheetName; }
public List<List<String>> getHead() { return head; }
public List<List<String>> getRows() { return rows; }
}
}
案例二
java
复制代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@RestController
public class ExportController {
private final UserService userService;
private final OrderService orderService;
private final ProductService productService;
private final CustomerService customerService;
private final InvoiceService invoiceService;
public ExportController(UserService userService,
OrderService orderService,
ProductService productService,
CustomerService customerService,
InvoiceService invoiceService) {
this.userService = userService;
this.orderService = orderService;
this.productService = productService;
this.customerService = customerService;
this.invoiceService = invoiceService;
}
@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
try {
CompletableFuture<List<User>> userFuture = CompletableFuture.supplyAsync(userService::list, executor);
CompletableFuture<List<Order>> orderFuture = CompletableFuture.supplyAsync(orderService::list, executor);
CompletableFuture<List<Product>> productFuture = CompletableFuture.supplyAsync(productService::list, executor);
CompletableFuture<List<Customer>> customerFuture = CompletableFuture.supplyAsync(customerService::list, executor);
CompletableFuture<List<Invoice>> invoiceFuture = CompletableFuture.supplyAsync(invoiceService::list, executor);
CompletableFuture<Void> all = CompletableFuture.allOf(userFuture, orderFuture, productFuture, customerFuture, invoiceFuture);
all.join(); // 等待全部完成
List<User> users = userFuture.join();
List<Order> orders = orderFuture.join();
List<Product> products = productFuture.join();
List<Customer> customers = customerFuture.join();
List<Invoice> invoices = invoiceFuture.join();
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("数据导出", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 写入多个 sheet
ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build();
writer.write(users, EasyExcel.writerSheet(0, "用户").head(User.class).build());
writer.write(orders, EasyExcel.writerSheet(1, "订单").head(Order.class).build());
writer.write(products, EasyExcel.writerSheet(2, "产品").head(Product.class).build());
writer.write(customers, EasyExcel.writerSheet(3, "客户").head(Customer.class).build());
writer.write(invoices, EasyExcel.writerSheet(4, "发票").head(Invoice.class).build());
writer.finish();
} finally {
executor.shutdown();
}
}
}
// 假设以下是实体类,省略 Getter/Setter
class User { private Long id; private String name; }
class Order { private Long id; private String number; }
class Product { private Long id; private String title; }
class Customer { private Long id; private String name; }
class Invoice { private Long id; private String invoiceNo; }
// 假设以下是 Service 接口
interface UserService { List<User> list(); }
interface OrderService { List<Order> list(); }
interface ProductService { List<Product> list(); }
interface CustomerService { List<Customer> list(); }
interface InvoiceService { List<Invoice> list(); }