Đọc file csv sử dụng opencsv

Có rất nhiều cách đọc file csv, nhưng đọc file như thế nào để tiện sử dụng sau này, mình chọn cách sử dụng thư viện opencsv để mapping Csv <—> POJO. Có được POJO rồi thì mình làm gì thì làm.

Note: POJO là Plain Old Java Object, chỉ dùng cho mục đích model data.

I. Cài đặt thư viện

Đầu tiên bạn cần import lib opencsv vào trong project.

Maven:

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.4</version>
</dependency>

Gradle

implementation group: 'com.opencsv', name: 'opencsv', version: '5.4'

II. Đọc file csv có header

First Name, LastName, Age, Address, Birthday
giang, nguyen, 30, Hanoi,01-01-1991
lucas, owen,,,20-01-2000
nam, Do, 10, Ninh Binh,15-05-1995

Bạn cần mapping file csv này với Class tương ứng

import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.CsvDate;
import lombok.Data;

import java.time.LocalDate;

@Data
public class PersonObject {
    @CsvBindByName(column = "First Name", required = true) (1)
    private String firstName;
    @CsvBindByName(column = "LastName")
    private String lastName;
    @CsvBindByName()
    private int age;
    @CsvBindByName()
    private String address; 
    @CsvBindByName()
    @CsvDate(value = "dd-MM-yyyy") (2)
    private LocalDate birthday;
}
  • (1) Mapping cột “First Name” với biến firstName
  • (2) Mapping date với kiểu định dạng “dd-MM-yyyy” với object LocalDate.

Test thử

@Test
void name() throws FileNotFoundException {
	List<PersonObject> list = new CsvToBeanBuilder<PersonObject>
      	(new FileReader("src/test/resources/data.csv"))
      	.withType(PersonObject.class)
      	.build().parse();

      list.forEach(System.out::println);
}
PersonObject(firstName=giang, lastName= nguyen, age=30, address= Hanoi, birthday=1991-01-01)
PersonObject(firstName=lucas, lastName= owen, age=0, address=, birthday=2000-01-20)
PersonObject(firstName=nam, lastName= Do, age=10, address= Ninh Binh, birthday=1995-05-15)

III. Đọc file csv không có header

giang,nguyen,30,Hanoi,01-01-1991
lucas,owen,1,HCM,20-01-2000
nam,Do,10,Ninh Binh,15-05-1995

Bạn cần phải mapping theo số thứ tự của cột

import com.opencsv.bean.CsvBindByPosition;
import com.opencsv.bean.CsvDate;
import lombok.Data;

import java.time.LocalDate;

@Data
public class NoHeaderCsvObject {
    @CsvBindByPosition(position = 0)
    private String firstName;
    @CsvBindByPosition(position = 1)
    private String lastName;
    @CsvBindByPosition(position = 2)
    private int age;
    @CsvBindByPosition(position = 3)
    private String address;
    @CsvBindByPosition(position = 4)
    @CsvDate(value = "dd-MM-yyyy")
    private LocalDate birthday;
}

Tương tự thì bạn cũng có thể test như sau.

@Test
void name2() throws FileNotFoundException {
	List<NoHeaderCsvObject> list = new CsvToBeanBuilder<NoHeaderCsvObject>
      	(new FileReader("src/test/resources/data2.csv"))
      	.withType(NoHeaderCsvObject.class)
      	.build().parse();

      list.forEach(System.out::println);
}
NoHeaderCsvObject(firstName=giang, lastName=nguyen, age=30, address=Hanoi, birthday=1991-01-01)
NoHeaderCsvObject(firstName=lucas, lastName=owen, age=1, address=HCM, birthday=2000-01-20)
NoHeaderCsvObject(firstName=nam, lastName=Do, age=10, address=Ninh Binh, birthday=1995-05-15)

IV. Tổng kết

Thư viện còn khá nhiều tùy biến hay ho nhưng mà mình không giới thiệu hết được (vì lười viết) nên chỉ nói 2 trường hợp cơ bản nhất thôi. Các bạn có thể đọc tiếp document của thư viện để biết thêm các trường hợp sử dụng khác.

Leave a Reply

Your email address will not be published. Required fields are marked *