如何將 Excel 資料轉換為 Java 物件列表
一、簡介
了解數據映射對於軟體開發至關重要。 Excel 是一種廣泛使用的資料管理軟體,因此對於 Java 開發人員來說了解如何在 Excel 和 Java 物件之間對應資料至關重要。
在本教學中,我們將探討如何將 Excel 資料轉換為 Java 物件清單。
Maven 儲存庫上提供了多個 Java 庫,可用於使用 Java 處理 Excel 文件,其中 Apache POI 是最常見的。然而,在本教學中,我們將使用四個 Java Excel 函式庫,包括 Apache POI、Poiji、FastExcel 和 JExcelApi (Jxl),將 Excel 資料轉換為 Java 物件清單。
2. 模型設定
首先,我們需要建立物件的藍圖, FoodInfo
類別:
public class FoodInfo {
private String category;
private String name;
private String measure;
private double calories;
// standard constructors, toString, getters and setters
}
3.阿帕契興趣點
Apache POI(Poor Obfuscation Implement)是用於 Microsoft 文件的 Java API。它是純 Java 庫的集合,用於從 Microsoft Office 文件(例如 Word、Outlook、Excel 等)讀取資料或向其中寫入資料。
3.1. Maven依賴
讓我們將Maven 依賴項新增到pom.xml
檔案中:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
3.2.將 Excel 資料轉換為物件列表
透過使用其Workbook
介面,我們可以存取各種功能來讀取 Excel 檔案的工作表和儲存格。此介面有兩種實現,一種適用於每種 Excel 格式 - HSSFWorkbook
for .xls
和XSSFWorkbook
for .xlsx
。
此程式碼片段使用 Apache POI 庫從.xlsx
檔案讀取 Excel 資料並將其轉換為FoodInfo
物件清單:
public static List<FoodInfo> excelDataToListOfObjets_withApachePOI(String fileLocation)
throws IOException {
FileInputStream file = new FileInputStream(new File(fileLocation));
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
List<FoodInfo> foodData = new ArrayList<FoodInfo>();
DataFormatter dataFormatter = new DataFormatter();
for (int n = 1; n < sheet.getPhysicalNumberOfRows(); n++) {
Row row = sheet.getRow(n);
FoodInfo foodInfo = new FoodInfo();
int i = row.getFirstCellNum();
foodInfo.setCategory(dataFormatter.formatCellValue(row.getCell(i)));
foodInfo.setName(dataFormatter.formatCellValue(row.getCell(++i)));
foodInfo.setMeasure(dataFormatter.formatCellValue(row.getCell(++i)));
foodInfo.setCalories(row.getCell(++i).getNumericCellValue());
foodData.add(foodInfo);
}
return foodData;
}
為了確定sheet
表物件中非空行的數量,我們使用getPhysicalNumberOfRows()
方法。然後,我們循環遍歷各行,不包括標題行 ( i = 1
)。
根據我們需要填充的食物物件的字段,我們可以使用dataFormatter
物件或getNumericValue()
方法來轉換單元格值並將其分配給適當的資料類型。
讓我們透過編寫單元測試來驗證我們的程式碼,以確保它使用名為food_info.xlsx
的 Excel 檔案按預期工作:
@Test
public void whenParsingExcelFileWithApachePOI_thenConvertsToList() throws IOException {
List<FoodInfo> foodInfoList = ExcelDataToListApachePOI
.excelDataToListOfObjets_withApachePOI("src\\main\\resources/food_info.xlsx");
assertEquals("Beverages", foodInfoList.get(0).getCategory());
assertEquals("Dairy", foodInfoList.get(3).getCategory());
}
Apache POI 庫為舊版本和新版本的 Excel 檔案(即.xls
和.xlsx
提供協助。
4. 普伊吉
Poiji 是一個線程安全的 Java 庫,它提供了用於從 Excel 工作表到 Java 類別的單向資料映射的 API 。它建構在 Apache POI 庫之上。但與 Apache POI 不同的是,它使用起來要簡單得多,並且直接將每個 Excel 行轉換為 Java 物件。
4.1.設定 Maven 依賴關係
以下是我們需要新增到pom.xml
檔案中的Poiji Maven 依賴項:
<dependency>
<groupId>com.github.ozlerhakan</groupId>
<artifactId>poiji</artifactId>
<version>4.1.1</version>
</dependency>
4.2.使用註釋設定類
Poiji 函式庫透過要求使用@ExcelCellName(String cellName)
或@ExcelCell(int cellIndex)
註解類別欄位來簡化 Excel 資料擷取。
下面,我們透過新增註解為 Poiji 庫設定FoodInfo
類別:
public class FoodInfo {
@ExcelCellName("Category")
private String category;
@ExcelCellName("Name")
private String name;
@ExcelCellName("Measure")
private String measure;
@ExcelCellName("Calories")
private double calories;
// standard constructors, getters and setters
}
此 API 支援會對應具有多個工作表的 Excel 工作簿。當我們的檔案有多個工作表時,我們可以在類別上使用@ExcelSheet(String sheetName)
註解來指示我們要使用哪個工作表。任何其他表都將被忽略。
但是,如果我們不使用此註釋,則只會考慮工作簿中的第一個 Excel 工作表。
在某些情況下,我們可能不需要從目標 Excel 工作表的每一行中提取資料。為了解決這個問題,我們可以@ExcelRow in our class
註解的private int
rowIndex
屬性。這將允許我們指定我們想要存取的行項目的索引。
4.3.將 Excel 資料轉換為物件列表
與本文中提到的函式庫不同,Poiji 函式庫預設會忽略 Excel 工作表的標題行。
以下程式碼片段從 Excel 檔案中擷取資料並將其資料轉換為FoodInfo:
public class ExcelDataToListOfObjectsPOIJI {
public static List<FoodInfo> excelDataToListOfObjets_withPOIJI(String fileLocation){
return Poiji.fromExcel(new File(fileLocation), FoodInfo.class);
}
}
程式將fileLocation file
的第一個 Excel 表轉換為FoodInfo
類別。每行都成為FoodInfo
類別的一個實例,其中單元格值代表物件的屬性。輸出是FoodInfo
物件的列表,其大小等於原始 Excel 工作表中的行數(不包括標題行)。
在某些情況下,密碼可以保護我們的 Excel 工作表。我們可以透過PoijiOptionsBuilder
定義密碼:
PoijiOptions options = PoijiOptionsBuilder.settings()
.password("<excel_sheet_password>").build();
List<FoodInfo> foodData = Poiji.fromExcel(new File(fileLocation), FoodInfo.class, options);
為了確保我們的程式碼能如預期運作,我們編寫一個單元測試:
@Test
public void whenParsingExcelFileWithPOIJI_thenConvertsToList() throws IOException {
List<FoodInfo> foodInfoList =
ExcelDataToListOfObjectsPOIJI
.excelDataToListOfObjets_withPOIJI("src\\main\\resources/food_info.xlsx");
assertEquals("Beverages", foodInfoList.get(0).getCategory());
assertEquals("Dairy", foodInfoList.get(3).getCategory());
}
5.快速Excel
FastExcel 是一個高效的庫,它佔用最少的內存,並為用 Java 創建和讀取基本 Excel 工作簿提供高效能。它專門支援較新版本的 Excel 檔案 ( .xlsx
),並且與 Apache POI 相比功能有限。
它只讀取儲存格內容,不包括圖形、樣式或其他儲存格格式。
5.1.設定 Maven 依賴關係
以下是加入pom.xml
**FastExcel和FastExcel reader Maven 依賴項**:
<dependency>
<groupId>org.dhatim</groupId>
<artifactId>fastexcel</artifactId>
<version>0.15.7</version>
</dependency>
<dependency>
<groupId>org.dhatim</groupId>
<artifactId>fastexcel-reader</artifactId>
<version>0.15.7</version>
</dependency>
5.2.將 Excel 資料轉換為物件列表
處理大型檔案時,FastExcel 閱讀器是一個不錯的選擇,儘管其功能有限。它很容易使用,**我們可以使用ReadableWorkbook
類別來存取整個 Excel 工作簿。**
這允許我們透過名稱或索引單獨檢索工作表。
在下面的方法中,我們從 Excel 工作表中讀取資料並將其轉換為FoodInfo
物件的清單:
public static List<FoodInfo> excelDataToListOfObjets_withFastExcel(String fileLocation)
throws IOException, NumberFormatException {
List<FoodInfo> foodData = new ArrayList<FoodInfo>();
try (FileInputStream file = new FileInputStream(fileLocation);
ReadableWorkbook wb = new ReadableWorkbook(file)) {
Sheet sheet = wb.getFirstSheet();
for (Row row: sheet.read()) {
if (row.getRowNum() == 1) {
continue;
}
FoodInfo food = new FoodInfo();
food.setCategory(row.getCellText(0));
food.setName(row.getCellText(1));
food.setMeasure(row.getCellText(2));
food.setCalories(Double.parseDouble(row.getCellText(3)));
foodData.add(food);
}
}
return foodData;
}
因為API讀取sheet
中的所有行(包括標題行) ,所以我們在循環行時需要跳過第一行(非從零開始的索引)。
存取單元格可以透過實例化Cell
類別來完成: Cell cell = row.getCell()
,它有兩種實現,一種採用int cellIndex
,另一種採用String cellAddress
(例如「C4」)參數。或直接取得單元格中的資料:例如row.getCellText().
無論哪種方式,在提取每個單元格的內容後,我們需要確保在必要時將其轉換為適當的food
對象欄位類型。
讓我們編寫一個單元測試來確保轉換有效:
@Test
public void whenParsingExcelFileWithFastExcel_thenConvertsToList() throws IOException {
List<FoodInfo> foodInfoList = ExcelDataToListOfObjectsFastExcel
.excelDataToListOfObjets_withFastExcel("src\\main\\resources/food_info.xlsx");
assertEquals("Beverages", foodInfoList.get(0).getCategory());
assertEquals("Dairy", foodInfoList.get(3).getCategory());
}
6.JExcelApi(Jxl)
JExcelApi(或 Jxl)是一個輕量級 Java 函式庫,用於讀取、寫入和修改 Excel 電子表格。
6.1.設定 Maven 依賴關係
讓我們將 JExcelApi 的 Maven 依賴項加入pom.xml
檔中:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
6.2.將 Excel 資料轉換為物件列表
雖然它只支援較舊的 Excel 格式 ( xls
) 文件,但JExcel 庫提供了一系列用於操作 Excel 文件的類別。 Workbook
類別用於存取文件中的 Excel 工作表清單。
下面的程式碼使用該庫將資料從.xls
檔案轉換為FoodInfo
物件清單foodData:
public static List<FoodInfo> excelDataToListOfObjets_withJxl(String fileLocation)
throws IOException, BiffException {
List<FoodInfo> foodData = new ArrayList<FoodInfo>();
Workbook workbook = Workbook.getWorkbook(new File(fileLocation));
Sheet sheet = workbook.getSheet(0);
int rows = sheet.getRows();
for (int i = 1; i < rows; i++) {
FoodInfo foodInfo = new FoodInfo();
foodInfo.setCategory(sheet.getCell(0, i).getContents());
foodInfo.setName(sheet.getCell(1, i).getContents());
foodInfo.setMeasure(sheet.getCell(2, i).getContents());
foodInfo.setCalories(Double.parseDouble(sheet.getCell(3, i).getContents()));
foodData.add(foodInfo);
}
return foodData;
}
由於庫不會忽略標題行,因此我們必須從i = 1
開始循環。工作表物件是一個從零開始的行索引列表。
使用 JExcel 庫檢索單元格資料與 FastExcel 庫非常相似。這兩個函式庫都使用具有兩種實作的getCell()
方法。
然而,在 JExcel 中,該方法是直接從Sheet
物件而不是Row
物件存取的。此外,JExcel 中getCell()
方法的實作之一採用兩個參數colNum
和rowNum
,這兩個參數都是整數: sheet.getCell(colNum, rowNum).
為了確保轉換順利進行,讓我們為我們的方法編寫一個單元測試:
@Test
public void whenParsingExcelFileWithJxl_thenConvertsToList()
throws IOException, BiffException {
List<FoodInfo> foodInfoList = ExcelDataToListOfObjectsJxl
.excelDataToListOfObjets_withJxl("src\\main\\resources/food_info.xls");
assertEquals("Beverages", foodInfoList.get(0).getCategory());
assertEquals("Dairy", foodInfoList.get(3).getCategory());
}
七、結論
在本文中,我們探討如何使用 Apache POI、Poiji、FastExcel 和 JExcelApi 等函式庫來讀取 Excel 檔案中的資料並將其轉換為 Java 物件。但是,選擇使用哪個庫取決於特定需求,並考慮每個庫的優點和限制。
例如,如果我們優先考慮從 Excel 檔案讀取資料並將其直接轉換為 Java 物件清單的最簡單方法,我們可能會選擇使用 Poiji 庫。
當談到 Java 中雙向 Excel 資料映射的效能和簡單性時,FastExcel 和 JExcelApi 程式庫是絕佳的選擇。然而,與 Apache POI 相比,它們提供的功能較少,後者是一個支援樣式和圖形的功能豐富的庫。
與往常一樣,本文的完整原始碼可在 GitHub 上取得。