使用 Apache POI 將 JDBC 結果集寫入 Excel 文件
1. 概述
數據處理是軟體開發中的關鍵任務之一。一個常見的用例是從資料庫檢索資料並將其匯出為用於進一步分析的格式,例如 Excel 檔案。
本教學將展示如何使用 Apache POI 庫將資料從 JDBC ResultSet
集匯出到 Excel 檔案。
2.Maven依賴
在我們的範例中,我們將從資料庫表中讀取一些資料並將其寫入 Excel 檔案中。讓我們在pom.xml
中定義Apache POI和POI OOXML 架構依賴項:
<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(dataPreparer.getSelectSql());) {
// The logic of export data to Excel file.
}
我們忽略了getConnection()
的實作細節。我們通常透過原始 JDBC 連線、連線池或從[DataSource](https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/javax/sql/DataSource.html)
取得 JDBC 連線。
4. 建立工作簿
Excel 檔案由一個orkbook
組成,並且可以包含多個工作表。在我們的演示中,我們將建立一個Workbook
和一個工作Sheet
,稍後將資料寫入其中。首先,讓我們建立一個Workbook
:
Workbook workbook = new XSSFWorkbook();
我們可以從 Apache POI 中選擇一些Workbook
變體:
-
HSSFWorkbook
– 舊版 Excel 格式 (97-2003) 產生器,副檔名為.xls
-
XSSFWorkbook
– 用於建立更新的、基於 XML 的 Excel 2007 格式(副檔名為.xlsx
) -
SXSSFWorkbook
– 也透過串流來建立擴展名為.xlsx
文件,從而將記憶體使用量保持在最低限度
對於本範例,我們將使用XSSFWorkbook
。但是,如果我們預計導出許多行,例如超過 10,000 行,那麼我們最好使用SXSSFWorkbook
而不是XSSFWorkbook
以獲得更有效率的記憶體利用率。
接下來,讓我們在orkbook
中建立一個名為「data」的Sheet
:
Sheet sheet = workbook.createSheet("data");
5. 建立標題行
通常,標題將包含資料集中每列的標題。由於我們在這裡處理從 JDBC 返回的ResultSet
對象,因此我們可以使用ResultSetMetaData
介面來提供有關ResultSet
列的元資料。
讓我們看看如何使用ResultSetMetaData
獲取列名稱並使用 Apache POI 建立 Excel 工作表的標題行:
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
,並且對於每次迭代,我們在工作表中建立一個新行。根據先前透過sheet.getLastRowNum()
在標題行中獲得的列號,我們對每一列進行迭代,以從目前行取得資料並寫入對應的 Excel 儲存格。
7. 寫練習冊
現在我們的Workbook
已完全填充,我們可以將其寫入 Excel 檔案。由於我們使用XSSFWorkbook
實例作為實現,因此匯出檔案將以 Excel 2007 檔案格式儲存,副檔名為.xslx
:
File excelFile = // our file
try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(excelFile))) {
workbook.write(outputStream);
workbook.close();
}
寫入後透過呼叫Workbook
實例上的close()
方法明確關閉Workbook
是一種很好的做法。這將確保資源已釋放並將資料刷新到檔案中。
現在,讓我們看看導出的結果,這些結果是根據我們的表定義的,並且還保持了資料的插入順序:
八、結論
在本文中,我們介紹如何使用 Apache POI 將資料從 JDBC ResultSet
集匯出到 Excel 檔案。我們建立了一個Workbook
,從ResultSetMetaData
動態填入標題行,並透過迭代ResultSet
用資料行填入工作表。
與往常一樣,程式碼可以在 GitHub 上取得。