In my application I use a lot of CSV files which I have to read and build a lists based on them. I'd like to discover an easy way to do this. Do you know any easy framework which does it without using number of config files etc?
For instance, I have got a class Person:
public class Person {
String name;
String surname;
double shoeSize;
boolean sex; // true: male, false:female
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public double getShoeSize() {
return shoeSize;
}
public void setShoeSize(double shoeSize) {
this.shoeSize = shoeSize;
}
public boolean isSe) {
return sex;
}
public void setSeboolean sex) {
this.sex = sex;
}
}
For this class, I have prepared CSV file:
name,surname,shoesize,sex
Tom,Tommy,32,true
Anna,Anny,27,false
How can I do it easily?
opencsv is a good and simple solution. It is a small but powerful library. You can download it from the opencsv website (direct download from sourceforge, use the jar in the
deploy
directory) or use maven.The java bean mapping feature makes it really simple because your CSV column names are matching the property names of your class (it ignores the different capitalisation).
How to use it:
That's all.
I think SuperCSV + Dozer easy to use and quite robust for java bean CSV serialization
http://supercsv.sourceforge.net/dozer.html
There are lot of good frameworks written in Java to parse a CSV file and form a List of Objects. OpenCSV, JSefa & jCSV are to name a few of them.
For your requirement, I believe jCSV suits the best. Below is the sample code from jCSV which you can make use of easily.
Moreover, parsing a CSV file and converting it to a List isn't a big deal and it can be achieved without using any framework, as shown below.
If the mapping of CSV columns to bean object is complex, repetitive or large in real case scenario, then it can be done easily by using DozerBeanMapper.
Hope this will help you.
Shishir
One of the simplest ways to read and serialize data is by using the Jackson library. It also has an extension for CSV, you can find the wiki here
Let's say you have a Pojo like this:
And a CSV like this:
Then reading it is done like so:
This is simple enough for my taste, basically all you need to do is add the column order in your CSV file using the
@JsonPropertyOrder
annotation and then just read the file using the above 2 lines.Not sure if you need to go as far as using an external library (and taking the usually implied performance hit). It's a pretty simple thing to implement. And if nothing else, it always helps to know what's going on behind the scenes in such a library:
Note that the catch statement uses Java 7 multi-catch. For older Java versions, either split it into 3 catch blocks or replace
ArrayIndexOutOfBoundsException|NumberFormatException|NullPointerException
withException
. The latter is usually discouraged as it masks and ignores all other exceptions as well, but in a simple example like this, the risk is probably not too high.This answer, unfortunately, is specific to your problem, but given that it is very straight forward, it should be easy to adapt to other situations as well...
Another neat thing you can do is to match
line
inside the while loop with a regular expression rather than simply splitting it based on a comma. That way you could also implement data validation in one shot (for example only match a sensible number for shoe size).Note that the above implementation doesn't work if you have names that contain commas which are then enclosed in quotes (like "Jackson, Jr." as a last name). You can cover this case "easily" if you use regular expressions as described above, or by checking the first letter of the last name and if it is a quotation mark, combine item[1] with item[2] and use item[3] and item[4] instead for the shoesize and sex. This special case will likely be covered by most of the external libraries suggested here, so if you're not worried about any dependencies, licensing issues, and performance hits, those might be the easier way out...
Use OpenCSV
Here is a complete example that reads entries and adds them to a List:
A
List
of typeString[]
is returned. You can iterate through the String array for each entry in the list and use the values at each index to populate your Bean constructor.