Bài viết gốc bạn có thể đọc ở đây.

Đây là một bài viết ngắn về cách ghi dữ liệu CSV và một vài gợi ý tốt nhất sẽ giúp mọi người có thể bắt đầu một cách đúng đắn.
 

Ghi file CSV sử dụng đúng ba dòng trong Java

Lại một lần nữa, Jackson làm điều này một cách khá dễ dàng. Đối với một file POJO bình thường với kiểu string đơn giản, date hoặc vài thuộc tính tương tự như vậy bạn có thể làm ghi file CSV với ba dòng code:
 

public String toCSV (List<YourPojo> listOfPojos){
    CsvMapper mapper = new CsvMapper();
    CsvSchema schema = mapper.schemaFor(YourPojo.class).withHeader();
    return mapper.writer(schema).writeValueAsString(listToSerialise);
}

 

Đoạn code trên xử lý chuyển đổi trạng thái (serialisation) khá đơn giản, dòng đầu tiên của file CSV sẽ ứng với các thuộc tính của file POJO đã được đánh dấu với kiểu chuyển đổi trạng thái (serialisation) đã được thiết lập sẵn. Ví dụ kiểu date sẽ được xuất ra theo kiểu thời gian.

Làm việc với các annations của Jackson

Để cải tiến output của bạn và biến đổi nó theo cách bạn thích thì bạn có thể sử dụng Jackson annotations. Nếu bạn muốn một file POJO đơn giản bạn có thể thêm @JsonPropertyOrder annotation để thiết lập thứ tự các cột và sử dụng @JsonFormat annotation để chắc chắn định dạng của dữ liệu của bạn theo cách bạn muốn. Còn nhiều thứ nữa, nhưng bạn đã có thể nắm được ý tưởng của việc này rồi chứ. Đây là code ví dụ nhé:

@JsonPropertyOrder(value = { "name", "dob"})
public class Person implements Serializable {
    private Date dob;
    private String name;
    
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    public Date getDob(){
        return dob;
    }
    public String getName(){
        return name;
    }
    //setters etc...
}

 

Yeah! Bây giờ thì ngày sinh của chúng ta đã chuyển sang định dạng mà loài người có thể đọc được.
 

Sử dụng Mixins

Có một chút hạn chế ở đây, nếu bạn làm theo cách trên thì các object của bạn sẽ nhanh chóng bị ô nhiễm vì các annotation chuyển đổi trạng thái (serialisation) đặc biệt(lời người dịch: ý là làm rối code, code không được clean). Và nếu bạn muốn định dạng JSON một kiểu và CSV một kiểu thì sao? 

Có một câu trả lời đó là sử dụng Mixins. Mixins là một class đã được đánh dấu bởi annotation đây là thứ giúp Jackson có thể sử dụng ‘overlay’ đánh dấu lên một class không được đánh đấu. Ví dụ bạn có thể xem dưới đây:

public class Person implements Serializable {
    private Date dob;
    public Date getDob(){
        return dob;
    }
}
 
public abstract class PersonFormat {
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    abstract Date getDob();
}

 

và yêu cầu Jackson áp dụng annotation từ abstract class, cụ thể như sau:
 

CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(Person.class).withHeader();
mapper.addMixInAnnotations(Person.class, PersonFormat.class);
mapper.writer(schema).writeValueAsString(listOfPeople);

 

Cool! Chúng ta đã có thể tách chuyển đổi định dạng dữ liệu từ object của chúng ta sang một method hoàn toàn riêng.  Chúng ta có thể lựa chọn cách field liên quan khi sử dụng chuyển đổi định dạng (serialising) sử dụng cặp đôi annotation là @JsonProperty và @JsonIgnore.

Nếu bạn hứng thú về mixins hãy khám phá thêm ở đây.

Lời người dịch:

Khi mình gặp vấn đề về việc đọc file POJO mà field có dạng là Date thì mình tìm thấy bài viết này. Vì vậy tương tự khi ta ghi file CSV thì ra có thể đọc file CSV có định dạng Date bằng cách thêm annotation @JsonFormat như ví dụ sau:

public class Person implements Serializable {
    private Date dob;
    private String name;
    
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    public Date getDob(){
        return dob;
    }
    public String getName(){
        return name;
    }
    //setters etc...
}