SuperCSV - CsvBeanReader, CellProcessor, CsvBeanWriter With Examples

SuperCSV motivation is to be the foremost, fastest, and most programmer-friendly, free CSV package for Java. Unfortunately we don’t have in-built CSV parser in java.

SuperCSV

There are many open source CSV parsers in java. But SuperCSV parser is my favourite. The power of Super CSV parser is the CellProcessor that gives a lot of features. You can specify a column value to be NotNull, Optional, Unique. SuperCSV cell processors also support Date Time conversion, Joda Time, Enum etc.

Today we will look into SuperCSV example to read CSV file and convert it to list of java object. We will also have a quick look of Super CSV example program to write CSV data.

Before we look into example, we have to create sample CSV data and corresponding java bean.


1,Pankaj Kumar,20,India
2,David Dan,40,USA
3,Lisa Ray,28,Germany

Our corresponding java bean class is Employee.java as defined below.


package com.journaldev.csv.model;
public class Employee {
	private String id;
	private String name;
	private String age;
	private String country;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	@Override
	public String toString() {
		return "{" + id + "::" + name + "::" + age + "::" + country + "}";
	}
}

SuperCSV Maven

Add below dependency in your maven project pom.xml file to get the Super CSV jar.


<dependency>
	<groupId>net.sf.supercsv</groupId>
	<artifactId>super-csv</artifactId>
	<version>2.4.0</version>
</dependency>

SuperCSV CsvBeanReader

Here is a simple Super CSV example program using CsvBeanReader to parse CSV data list of java object.


package com.journaldev.csv.supercsv.parser;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
import com.journaldev.csv.model.Employee;
public class SuperCSVParserExample {
	public static void main(String[] args) throws IOException {
		List<Employee> emps = new ArrayList<Employee>();
		ICsvBeanReader beanReader = new CsvBeanReader(new FileReader("emps.csv"), CsvPreference.STANDARD_PREFERENCE);
		// the name mapping provide the basis for bean setters
		final String[] nameMapping = new String[] { "id", "name", "age", "country" };
		//to read and skip header row
		//final String[] header = beanReader.getHeader(true);
		final CellProcessor[] processors = getProcessors();
		Employee emp;
		while ((emp = beanReader.read(Employee.class, nameMapping, processors)) != null) {
			emps.add(emp);
		}
		System.out.println(emps);
		beanReader.close();
	}
	private static CellProcessor[] getProcessors() {
		final CellProcessor[] processors = new CellProcessor[] {
				new UniqueHashCode(), // ID
				new NotNull(), // Name
				new Optional(), // Age
				new NotNull() // Country
		};
		return processors;
	}
}

The program is simple to understand, most important part is the creation of Super CSV cell processors.

If your CSV file contains header row, then use beanReader.getHeader(true) to read and skip the header for processing.

SuperCSV CsvBeanWriter

A simple Super CSV example using CsvBeanWriter to write CSV data. I am assuming that age and country fields are optional.


package com.journaldev.csv.supercsv.parser;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
import com.journaldev.csv.model.Employee;
public class SuperCSVWriterExample {
	public static void main(String[] args) throws IOException {
		List<Employee> emps = generateDemoData();
		StringWriter writer = new StringWriter();
		ICsvBeanWriter beanWriter = new CsvBeanWriter(writer, CsvPreference.STANDARD_PREFERENCE);
		final String[] header = new String[] { "id", "name", "age", "country" };
		final CellProcessor[] processors = getProcessors();
		// write the header
		beanWriter.writeHeader(header);
		// write the beans data
		for (Employee emp : emps) {
			beanWriter.write(emp, header, processors);
		}
		beanWriter.close();
		System.out.println("CSV Datan" + writer.toString());
	}
	private static CellProcessor[] getProcessors() {
		final CellProcessor[] processors = new CellProcessor[] { new UniqueHashCode(), // ID
				new NotNull(), // Name
				new Optional(), // Age
				new Optional() // Country
		};
		return processors;
	}
	private static List<Employee> generateDemoData() {
		List<Employee> emps = new ArrayList<>();
		Employee emp = new Employee();
		emp.setId("1");
		emp.setName("Pankaj Kumar");
		emp.setAge("30"); // country is optional and not set
		Employee emp1 = new Employee();
		emp1.setId("2");
		emp1.setName("David");
		emp1.setCountry("USA"); // age is optional
		Employee emp2 = new Employee();
		emp2.setId("3");
		emp2.setName("Lisa");
		emp2.setAge("20");
		emp2.setCountry("India");
		emps.add(emp);
		emps.add(emp1);
		emps.add(emp2);
		return emps;
	}
}

Above program produce below CSV output.


CSV Data
id,name,age,country
1,Pankaj Kumar,30,
2,David,,USA
3,Lisa,20,India

If you don’t want header row, then comment the code beanWriter.writeHeader(header) in above program.

If the above program is changed to keep the id of two Employee objects same, then we will get below exception.


Exception in thread "main" org.supercsv.exception.SuperCsvConstraintViolationException: duplicate value '2' encountered with hashcode 50
processor=org.supercsv.cellprocessor.constraint.UniqueHashCode
context={lineNo=4, rowNo=4, columnNo=1, rowSource=[2, Lisa, 20, India]}
	at org.supercsv.cellprocessor.constraint.UniqueHashCode.execute(UniqueHashCode.java:78)
	at org.supercsv.util.Util.executeCellProcessors(Util.java:93)
	at org.supercsv.io.CsvBeanWriter.write(CsvBeanWriter.java:136)
	at com.journaldev.csv.supercsv.parser.SuperCSVWriterExample.main(SuperCSVWriterExample.java:33)

The reason is that we have defined id column to have UniqueHashCode constraint. This is a very unique and important feature, missing in all the other CSV parsers in java.

That’s all for a quick SuperCSV tutorial.

Reference: SuperCSV Home Page

By admin

Leave a Reply

%d bloggers like this: