일단 spring boot 프로젝트(저는 v.3.3.3
사용) 하나 생성하고,
pom.xml 에 아래와 같이 의존성을 추가합니다.
<!-- jdk 버전은 22 사용 -->
<properties>
<java.version>22</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
<!-- 예시 코드를 모두 junit test 로 작성했습니다. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 편의를 위한 롬복 추가 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
</dependencies>
코드 전체 내용이 궁금하시면 제 깃헙 리포지토리에서 확인 가능합니다.
@Test
void readTest() {
// read file
var csvFile = new ClassPathResource("sample_csv/customers-100.csv");
// there is header row in our csv!
CsvSchema schema = CsvSchema.emptySchema().withHeader();
//.withNullValue(""); // 공백 => null 로 치환하는 옵션
// create Reader For Csv File
ObjectReader objectReader = new CsvMapper().readerFor(Customer.class).with(schema);
try (InputStream inputStream = csvFile.getInputStream();
MappingIterator<Customer> iterator = objectReader.readValues(inputStream)) {
while (iterator.hasNext()) {
System.out.println("next = " + iterator.next());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* <h2>CSV 파일의 내용을 Pojo 로 읽기 위한 클래스</h2>
* 각각의 필드 위에 @JsonProperty("CSV_컬럼명") 처럼 작성합니다. <br>
* 참고로 꼭 커스텀하게 Pojo 를 생성할 필요없이ㅏ Map<String,String> 으로 <br>
* CSV 내용을 조회할 수도 있습니다.
*/
record Customer(
@JsonProperty("Index")
String index,
@JsonProperty("Customer Id")
String customerId,
@JsonProperty("First Name")
String firstName,
@JsonProperty("Last Name")
String lastName,
@JsonProperty("Company")
String company,
@JsonProperty("City")
String city,
@JsonProperty("Country")
String country,
@JsonProperty("Phone 1")
String phone1,
@JsonProperty("Phone 2")
String phone2,
@JsonProperty("Email")
String email,
@JsonProperty("Subscription Date")
String subscriptionDate,
@JsonProperty("Website")
String website
) {}
여기서 쓰이는 CSV 제 깃헙 리포지토리에서 확인하시기 바랍니다.
@Test
void readTestWithEncoding() {
// read file
var csvFile = new ClassPathResource("sample_csv/customers-100.csv");
// there is header row in our csv!
CsvSchema schema = CsvSchema.emptySchema().withHeader();
//.withNullValue(""); // 공백 => null 로 치환하는 옵션
// create Reader For Csv File which will eventually create Map instance
ObjectReader objectReader = new CsvMapper().readerFor(new TypeReference<Map<String, String>>() {}).with(schema);
// 여기서 인코딩 지정!
try (InputStreamReader isr =
new InputStreamReader(csvFile.getInputStream(), Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr);
MappingIterator<Map<String, String>> iterator = objectReader.readValues(br)) {
while (iterator.hasNext()) {
System.out.println("next = " + iterator.next());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
@Description("Writing list of pojo to CSV")
void writeTest() {
// need to create schema for csv file's first row definition
CsvSchema schema = CsvSchema.builder().
addColumn("firstName").addColumn("lastName").build()
.withHeader();
//.withNullValue(""); // 공백 => null 로 치환하는 옵션
// create writer
ObjectWriter writer =
new CsvMapper()
.writerFor(new TypeReference<List<Name>>() {})
.with(schema);
// create List of Pojo to Insert into CSV File (or outputStream, Writer, etc...)
List<Name> names = List.of(
Name.builder().firstName("daily").lastName("code").build(),
Name.builder().firstName("coding").lastName("toast").build(),
Name.builder().firstName("hello").lastName("world").build()
);
// Write Csv Data
try {
// StringWriter 는 굳이 close 할 필요 X
// 다른 Writer 면 try-with-resource 구문 사용!
StringWriter stringWriter = new StringWriter();
writer.writeValue(stringWriter, names);
System.out.println(stringWriter);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Builder
record Name(
@JsonProperty("firstName") String firstName,
@JsonProperty("lastName") String lastName
) {}