CSV stands for ‘comma-separated values‘. CSV files are mostly used for creating data files for exporting or importing the data. Java language does not provide any native support for effectively handling CSV files. Without using 3rd party libraries, we may end up creating your own CSV parser. There is usually no advantage in re-inventing the wheel, so using such 3rd party tools for parsing the CSV files is advisable.
OpenCSV is a tool that can be used to read a CSV file in java or write data to a CSV file.
1. Setting Up
If we are working on a Maven project, we can include the latest OpenCSV maven dependency in pom.xml
file like below.
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.7.0</version>
</dependency>
In this tutorial, we will be reading and writing the following file in all examples. We have placed this file in the application’s /resources folder.
ID,FNAME,LNAME,COUNTRY,AGE
1,Lokesh,Gupta,India,32
2,David,Miller,England,34
2. OpenCSV Core Classes
Below is a list of the most used OpenCSV classes which we should go through.
- CSVParser: A very simple CSV parser released under a commercial-friendly license. This just implements splitting a single line into fields.
- CSVReader: You will be using this class most of the time while reading a CSV file from your java application code. This class provides a number of useful constructors to build CSVReader with different options and capabilities. e.g. you can supply a different separator character (default is comma), a different quote character (default is double-quote) and even you can supply the initial line number from where parsing should start.
- CSVWriter: CSVWriter is also very customizable just like
CSVReader
. You can use custom separator, custom quote character or custom line terminator while writing a CSV file using your java application code. - CsvToBean: This class will be used when you want to populate your java beans from a CSV file content. You will see an example below.
- BeanToCsv: If you want to export data to CSV file from your java application, you might need help of this class as well.
- ColumnPositionMappingStrategy: If you plan to use CsvToBean (or BeanToCsv) for importing CSV data, you will use this class to map CSV fields to java bean fields.
3. Parsing and Reading a CSV File
3.1. Reading a CSV file Line by Line
As mentioned above, to read a CSV file we will take the help of CSVReader
class. Let’s look at a quick example for reading a CSV file line by line.
- We can use CSVParserBuilder to supply any custom seperator character.
- We can use CSVReaderBuilder to specify the number of lines to skip. This is useful is the CSV file has headers in the first row and we do not wish to read headers.
import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import java.io.FileReader;
import java.net.URL;
import java.util.Arrays;
public class ParseCSVLineByLine {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
URL fileUrl = ParseCSVLineByLine.class.getClassLoader().getResource("data.csv");
//Build reader instance
//Read data.csv
//Default separator is comma
//Start reading from line number 2 (line numbers start from zero)
CSVParser csvParser = new CSVParserBuilder()
.withSeparator(',')
.withIgnoreQuotations(true)
.build();
CSVReader csvReader = new CSVReaderBuilder(new FileReader(fileUrl.getFile()))
.withSkipLines(1)
.withCSVParser(csvParser)
.build();
//Read CSV line by line and use the string array as you want
String[] nextLine;
while ((nextLine = csvReader.readNext()) != null) {
if (nextLine != null) {
//Verifying the read data here
System.out.println(Arrays.toString(nextLine));
}
}
}
}
3.2. Reading Complete CSV File and Iterating through Lines
The above example read the CSV file line by line and print to the console. We can read the complete CSV file once and then iterate over data as we want. Below is an example of building CSV data read using readAll()
method.
import com.opencsv.CSVReader;
import java.io.FileReader;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
public class ParseFullCSVExample {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
URL fileUrl = ParseCSVLineByLine.class.getClassLoader().getResource("data.csv");
//Build reader instance
CSVReader reader = new CSVReader(new FileReader(fileUrl.getFile()));
//Read all rows at once
List<String[]> allRows = reader.readAll();
//Read CSV line by line and use the string array as you want
for (String[] row : allRows) {
System.out.println(Arrays.toString(row));
}
}
}
4. Writing into a CSV File
Writing a CSV file is as simple as reading it. Create an instance of CSVWriter
with appropriate configuration options and start writing data to CSV file.
Notice the optional second argument in writeNext(nextLine, applyQuotesToAll). When we set applyQuotesToAll to true then all the values written in the CSV file are without double quotes.
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.net.URL;
public class WritingCSVFileExample {
public static void main(String[] args) throws Exception {
URL fileUrl = WritingCSVFileExample.class.getClassLoader().getResource("data.csv");
CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile()));
//Create record
String[] record = "2,Rahul,Vaidya,India,35".split(",");
//Write the record to file
writer.writeNext(record, false);
//close the writer
writer.close();
}
}
5. Appending to an Existing CSV file
The previous example creates a new CSV file and starts writing data from start i.e. line number 0. Many times we want to append data to an existing CSV file instead of writing a new file. We can achieve this functionality by passing the append mode as the second argument to FileWriter
instance.
CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile(), true));
There is no direct support for appending in OpenCSV library.
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.net.URL;
public class WritingCSVFileExample {
public static void main(String[] args) throws Exception {
URL fileUrl = WritingCSVFileExample.class.getClassLoader().getResource("data.csv");
CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile(), true));
//Create record
String[] record = new String[]{"3","Rahul","Vaidya","India","35"};
//Write the record to file
writer.writeNext(record, false);
//close the writer
writer.close();
}
}
Now check the data.csv file.
ID,FNAME,LNAME,COUNTRY,AGE
1,Lokesh,Gupta,India,32
2,David,Miller,England,34
3,Rahul,Vaidya,India,35
7. Reading CSV to Java Bean
OpenCSV also provides functionality to read CSV files to Java beans directly. Suppose the Java POJO is Employee class. For keeping things simple, we are creating all fields of String type.
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee
{
private String id;
private String firstName;
private String lastName;
private String country;
private String age;
}
Below example read the data.csv file and populate the instances of Employee. Then it verifies the data by printing it on the console.
import com.opencsv.CSVReader;
import com.opencsv.bean.ColumnPositionMappingStrategy;
import com.opencsv.bean.CsvToBean;
import java.io.FileReader;
import java.net.URL;
import java.util.List;
public class CSVMappedToJavaBeanExample {
@SuppressWarnings({"rawtypes", "unchecked"})
public static void main(String[] args) throws Exception {
URL fileUrl = CSVMappedToJavaBeanExample.class.getClassLoader().getResource("data.csv");
CSVReader csvReader = new CSVReader(new FileReader(fileUrl.getFile()));
CsvToBean csv = new CsvToBean();
csv.setCsvReader(csvReader);
csv.setMappingStrategy(setColumMapping());
List list = csv.parse();
for (Object object : list) {
Employee employee = (Employee) object;
System.out.println(employee);
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static ColumnPositionMappingStrategy setColumMapping() {
ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy();
strategy.setType(Employee.class);
String[] columns = new String[]{"id", "firstName", "lastName", "country", "age"};
strategy.setColumnMapping(columns);
return strategy;
}
}
Program Output.
Employee(id=ID, firstName=FNAME, lastName=LNAME, country=COUNTRY, age=AGE)
Employee(id=1, firstName=Lokesh, lastName=Gupta, country=India, age=32)
Employee(id=2, firstName=David, lastName=Miller, country=England, age=34)
Employee(id=3, firstName=Rahul, lastName=Vaidya, country=India, age=35)
8. Creating CSV from SQL Data
Now, this is also a desired activity we will need in the applications. For exporting data directly from SQL tables to CSV files, we will need the ResultSet object. The following API can be used to write data to CSV from ResultSet
using obtained ResultSet reference.
java.sql.ResultSet myResultSet = getResultSetFromSomewhere();
writer.writeAll(myResultSet, includeHeaders); //writer is instance of CSVWriter
In the above method, the first argument is the ResultSet
which we want to write to CSV file. And the second argument is boolean
which represents whether we want to write header columns (table column names) to file or not.
9. Conclusion
This tutorial explained the basic usage of the OpenCSV library to read and write CSV files from a Java application code. We learned to read a CSV file line by line, and whole file in one go. We also learned to configure the reader to supply custom separator and skipping lines incase the file has column names header as first line.
Finally, we learned to write the CSV data into a new File, and appending to an existing CSV file.
Happy Learning !!
Leave a Reply