如何從 POJO 建立具有自訂列標題和位置的 CSV 文件
1. 概述
CSV 是系統和應用程式之間常見的資料交換格式之一。一個常見的用例是建立處理這些 CSV 檔案的 Java 應用程式。將資料寫入 CSV 檔案時,我們需要將普通舊 Java 物件 ( POJO ) 對應到 CSV 格式。
在本教程中,我們將學習如何使用自訂位置和標題名稱將 POJO 對應到 CSV 格式。
2.OpenCSV庫
OpenCSV是一個非常受歡迎的用來處理 CSV 檔案的函式庫。我們首先需要在我們的專案中新增 Maven 依賴項:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.8</version>
</dependency>
3. 產生輸入記錄
在本文中,我們將產生範例輸入記錄,並將其對應到 CSV 記錄。
3.1.申請記錄
應用程式記錄是一個簡單的 POJO,其中包含id, name, age,
和created_at
欄位:
public record Application(String id, String name, Integer age, String created_at) {}
3.2.應用程式列表
我們將產生一個應用程式列表,稍後將其轉換為 CSV 格式:
List<Application> applications = List.of(
new Application("123", "Sam", 34, "2023-08-11"),
new Application("456", "Tam", 44, "2023-02-11"),
new Application("890", "Jam", 54, "2023-03-11")
);
4. POJO 轉 CSV
POJO 到 CSV 的預設對映非常簡單。我們可以使用定義的分隔符號和其他配置的StatefulBeanToCsvBuilder
,然後我們可以使用FilerWriter
來寫它:
public static void beanToCSVWithDefault(List<Application> applications) throws Exception {
try (FileWriter writer = new FileWriter("application.csv")) {
var builder = new StatefulBeanToCsvBuilder<Application>(writer)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.withSeparator(',')
.build();
builder.write(applications);
}
}
預設映射將 POJO 轉換為具有升序欄位名稱的 CSV,但如果我們希望標頭採用自訂格式,則它沒有幫助。
4.1.自訂標頭策略
如果我們希望輸出 CSV 檔案具有自訂標頭,則可以在寫入 CSV 檔案時定義並使用自訂標頭策略。
例如,如果我們希望標頭名稱為小寫,我們可以重寫generateHeader:
public class CustomCSVWriterStrategy<T> extends HeaderColumnNameMappingStrategy<T> {
@Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
String[] header = super.generateHeader(bean);
return Arrays.stream(header)
.map(String::toLowerCase)
.toArray(String[]::new);
}
}
一旦我們有了自訂的標頭映射策略,我們就可以建立StatefulBeanToCsvBuilder
,然後將 POJO 以 CSV 格式寫入 CSV 檔案:
public static void beanToCSVWithCustomHeaderStrategy(List<Application> applications)
throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {
try (FileWriter writer = new FileWriter("application.csv")){
var mappingStrategy = new CustomCSVWriterStrategy<Application>();
mappingStrategy.setType(Application.class);
var builder = new StatefulBeanToCsvBuilder<Application>(writer)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.withMappingStrategy(mappingStrategy)
.build();
builder.write(applications);
}
}
4.2.客製化倉位策略
也可以使用具有特定定義位置的 CSV 欄位寫入 CSV 檔案。我們所要做的就是使用所需的欄位位置註解應用程式記錄屬性:
public record Application(
@CsvBindByPosition(position = 0)
String id,
@CsvBindByPosition(position = 1)
String name,
@CsvBindByPosition(position = 2)
Integer age,
@CsvBindByPosition(position = 3)
String created_at) {}
現在,我們可以使用帶有註釋的Application
記錄將POJO
寫入CSV
格式:
public static void beanToCSVWithCustomPositionStrategy(List<Application> applications) throws Exception {
try (FileWriter writer = new FileWriter("application3.csv")) {
var builder = new StatefulBeanToCsvBuilder<Application1>(writer)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.build();
builder.write(applications);
}
}
4.3.自訂倉位策略和標題名稱
如果我們希望 CSV 欄位與標題一起位於某個位置,我們可以使用自訂列定位策略來實現。
首先,我們需要使用位置和標題名稱來註解應用程式記錄類別屬性:
public record Application1(
@CsvBindByName(column = "id", required = true)
@CsvBindByPosition(position = 1)
String id,
@CsvBindByName(column = "name", required = true)
@CsvBindByPosition(position = 0)
String name,
@CsvBindByName(column = "age", required = true)
@CsvBindByPosition(position = 2)
Integer age,
@CsvBindByName(column = "position", required = true)
@CsvBindByPosition(position = 3)
String created_at) {}
一旦記錄類別準備好了,我們就需要編寫自訂的列定位策略。
此策略將包括生成標題和欄位位置的邏輯:
public class CustomColumnPositionStrategy<T> extends ColumnPositionMappingStrategy<T> {
@Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
super.generateHeader(bean);
return super.getColumnMapping();
}
}
現在我們已經完成了記錄和列定位策略,我們準備在客戶端邏輯中使用它們並產生 CSV 檔案:
public static void beanToCSVWithCustomHeaderAndPositionStrategy(List<Application1> applications)
throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {
try (FileWriter writer = new FileWriter("application4.csv")){
var mappingStrategy = new CustomColumnPositionStrategy<Application1>();
mappingStrategy.setType(Application1.class);
var builder = new StatefulBeanToCsvBuilder<Application1>(writer)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.withMappingStrategy(mappingStrategy)
.build();
builder.write(applications);
}
}
5. 結論
在本教程中,我們學習如何將 POJO 轉換為 CSV 格式並寫入 CSV 檔案。我們討論並編寫了包含標題和 CSV 欄位的範例。此外,我們還編寫了自訂標題和定位策略。
OpenCSV 沒有提供開箱即用的解決方案來為 CSV 檔案提供自訂定位和標題,但可以輕鬆編寫自訂策略以在所需位置包含欄位和標題。
與往常一樣,範例程式碼可以在 GitHub 上取得。