1. 概述

数据处理是软件开发中的核心任务之一。常见场景是从数据库提取数据并导出为Excel等格式供后续分析。

本文将演示如何使用Apache POI库将JDBC的ResultSet导出为Excel文件。

2. Maven依赖

我们将从数据库表读取数据并写入Excel文件。首先在pom.xml中添加Apache POIPOI OOXML schema依赖:

<dependency> 
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId> 
    <version>5.3.0</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml</artifactId> 
    <version>5.3.0</version> 
</dependency>

演示使用H2数据库,同时添加其依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.3.232</version>
</dependency>

3. 数据准备

在H2数据库中创建products表并插入测试数据:

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255) NOT NULL, 
    category VARCHAR(255), 
    price DECIMAL(10, 2) 
);

INSERT INTO products(name, category, price) VALUES ('Chocolate', 'Confectionery', 2.99);
INSERT INTO products(name, category, price) VALUES ('Fruit Jellies', 'Confectionery', 1.5);
INSERT INTO products(name, category, price) VALUES ('Crisps', 'Snacks', 1.69);
INSERT INTO products(name, category, price) VALUES ('Walnuts', 'Snacks', 5.95);
INSERT INTO products(name, category, price) VALUES ('Orange Juice', 'Juices', 2.19);

通过JDBC获取products表数据:

try (Connection connection = getConnection();
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT * FROM products");) {
    // 导出Excel的逻辑
}

⚠️ getConnection()的实现细节省略了。通常我们通过原生JDBC连接连接池DataSource获取连接。

4. 创建工作簿

Excel文件由工作簿(Workbook)组成,可包含多个工作表(Sheet)。我们创建一个Workbook和单个Sheet

Workbook workbook = new XSSFWorkbook();

Apache POI提供三种Workbook实现:

  • HSSFWorkbook:生成旧版Excel格式(97-2003),扩展名.xls
  • XSSFWorkbook:生成新版Excel 2007格式(XML-based),扩展名.xlsx
  • SXSSFWorkbook:流式生成.xlsx文件,内存占用更低

✅ 本例使用XSSFWorkbook。但若导出超过10,000行数据,建议改用SXSSFWorkbook以优化内存使用。

接着创建名为"data"的工作表:

Sheet sheet = workbook.createSheet("data");

5. 创建表头行

表头通常包含数据集的列名。利用ResultSetResultSetMetaData获取列元数据:

Row row = sheet.createRow(sheet.getLastRowNum() + 1);
for (int n = 0; n < numOfColumns; n++) {
    String label = resultSetMetaData.getColumnLabel(n + 1);
    Cell cell = row.createCell(n);
    cell.setCellValue(label);
}

✅ 通过ResultSetMetaData动态获取列名作为Excel表头,避免硬编码列名。

6. 创建数据行

添加表头后,将表数据写入Excel:

while (resultSet.next()) {
    Row row = sheet.createRow(sheet.getLastRowNum() + 1);
    for (int n = 0; n < numOfColumns; n++) {
        Cell cell = row.createCell(n);
        cell.setCellValue(resultSet.getString(n + 1));
    }
}

遍历ResultSet时:

  1. 为每条记录创建新行
  2. 根据列数遍历当前行数据
  3. 将数据写入对应Excel单元格

7. 写入工作簿

数据填充完成后,将Workbook写入文件。由于使用XSSFWorkbook,文件保存为.xlsx格式:

File excelFile = new File("products.xlsx");
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(excelFile))) {
    workbook.write(outputStream);
    workbook.close();
}

⚠️ 务必显式调用workbook.close()释放资源并确保数据刷新到文件。

导出结果如下(按表结构定义且保持数据插入顺序):

导出的Excel文件

8. 总结

本文演示了使用Apache POI将JDBC ResultSet导出为Excel文件的完整流程:

  1. 创建Workbook和工作表
  2. 通过ResultSetMetaData动态生成表头
  3. 遍历ResultSet填充数据行
  4. 将工作簿写入文件

这种方案简单粗暴,特别适合中小规模数据导出。处理大数据量时记得切换到SXSSFWorkbook避免内存踩坑。