Convert CSV to Java Obejct with Spring(1) - Comma or Tab delimiter with OpenCSV
- Get link
- X
- Other Apps
Introduction
Spring batch provides tools to load csv, but I need really simple solution to load CSV to import some of data. From this tutorial, I will show you how to load CSV file to Java Object List.
Tools
- Spring STS
- Java
- OpenCSV
Reference
Youtube video
OpenCSV Annotation and Mapping Strategy
This statement came from OpenCSV manaul
The most powerful mechanism opencsv has for reading and writing CSV files involves defining beans that the fields of the CSV file can be mapped to and from, and annotating the fields of these beans so opencsv can do the rest. In brief, these annotations are:
- CsvBindByName: Maps a bean field to a field in the CSV file based on the name of the header for that field in the CSV input.
- CsvBindByPosition: Maps a bean field to a field in the CSV file based on the numerical position of the field in the CSV input.
- CsvCustomBindByName: The same as CsvBindByName, but must provide its own data conversion class.
- CsvCustomBindByPosition: The same as CsvBindByPosition, but must provide its own data conversion class.
- CsvDate: Must be applied to bean fields of date/time types for automatic conversion to work, and must be used in conjunction with one of the preceding four annotations. As you can infer, there are two strategies for annotating beans, depending on your input:
Annotating by header name Annotating by column position It is possible to annotate bean fields both with header-based and position-based annotations. If you do, position-based annotations take precedence if the mapping strategy is automatically determined. To use the header-based annotations, you would need to instantiate and pass in a HeaderColumnNameMappingStrategy. When might this be useful? Possibly reading two different sources that provide the same data, but one includes headers and the other doesn't. Possibly to convert between headerless input and output with headers. Further use cases are left as an exercise for the reader.
Most of the more detailed documentation on using annotations is in the section on reading data. The use of annotations applies equally well to writing data, though; the annotations define a two-way mapping between bean fields and fields in a CSV file. Writing is then simply reading in reverse.
Createing CSV Entity Class from Spring
There are two ways to load data, but I recommend to mapping CSV files to class instead of handling string.
Sample tab deliminated text file
division itemcode description assortment
100 10000062 test item 1 1090
100 10000063 test item 2 1020
100 10000064 test item 3 1090
100 10000193 test item 4 1030
CSVItem.java
package com.flairpackaging.exact.datamanager.imports.csv.entity;
import com.opencsv.bean.CsvBindByName;
public class CSVItem {
@CsvBindByName(column="division", required = true)
String division;
@CsvBindByName
String itemcode;
@CsvBindByName
String description;
@CsvBindByName
String assortment;
public String getDivision() {
return division;
}
public void setDivision(String division) {
this.division = division;
}
public String getItemcode() {
return itemcode;
}
public void setItemcode(String itemcode) {
this.itemcode = itemcode;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getAssortment() {
return assortment;
}
public void setAssortment(String assortment) {
this.assortment = assortment;
}
}
adding opencsv to the pom.xml file
<properties>
...
<opencsv.version>4.0</opencsv.version>
</properties>
<dependencies>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>${opencsv.version}</version>
</dependency>
...
</dependencies>
CSVItemService.java
public void loadItemCSV(String filename, char separator) {
try {
List<CSVItem> beans = new CsvToBeanBuilder(new FileReader(filename))
.withType(CSVItem.class).withSeparator(separator).build().parse();
Iterator<CSVItem> iterator = beans.iterator();
while (iterator.hasNext()) {
CSVItem csvItem = iterator.next();
System.out.println("Loading: " + csvItem.toString());
}
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Handling quotation from data
If data contains quotations such as double quote, following option should be entered.
.withIgnoreQuotations(true)
List<CSVItem> beans = new CsvToBeanBuilder(new FileReader("d:/test-item.txt"))
.withType(CSVItem.class).withSeparator('\t').withIgnoreQuotations(true).build().parse();
Error: Not reading first column header
If the first column of header doesn't read, please try to save with UTF-8 again. In my case, the csv file have some wired hidden character due to file encoding and this caused the issue.
This shows the file encoding type. I used Sublime to check the file type
As you see the below screen, the first charact has been read as part of first column header string.
Summary
Please keep in mind that depending on the encoding format of text file, the first heading column can't be read. This can be happened to users who deal with non-english characters. There are more examples from the reference site, so please refer the official site for the OpenCSV.
Comments
Post a Comment