[Java] Jackson 으로 CSV 읽기/쓰기

식빵·2024년 9월 4일
0

Java Lab

목록 보기
27/29

프로젝트 세팅

일단 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>




코드

코드 전체 내용이 궁금하시면 제 깃헙 리포지토리에서 확인 가능합니다.


UTF-8 인코딩 CSV 파일 읽기

@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();
	
	// 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();

	// 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();
	
	// 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
) {}
profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글