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, 1 object bình thường như bao object khác.
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
Giả sử bạn có file data.csv như sau:
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.