Csv to java objects

How to read and write CSV files using OpenCSV

In an earlier article, I discussed how to read and write CSV files using Apache Commons CSV. This article is a direct continuation of the previous article and part of the series about libraries that can be used to read and write CSV files in Java.

Today, we shall learn about another open-source library, OpenCSV, to read and write CSV files in Java. OpenCSV is another popular library for reading, writing, parsing, serializing, and deserializing CSV files in Java.

Before we move on to parsing or writing CSV files, you only need OpenCSV dependency for your project. If you are using Gradle, add the following dependency to the build.gradle file:

implementation 'com.opencsv:opencsv:4.6' 
dependency> groupId>com.opencsvgroupId> artifactId>opencsvartifactId> version>4.6version> dependency> 

Let us use the same CSV files we used for the Commons CSV examples for reading and parsing using OpenCSV. Here is the first CSV without a header: users.csv

1,Atta Shah,atta@example.com,PK 2,Alex Jones,alex@example.com,DE 3,Jovan Lee,jovan@example.com,FR 4,Greg Hover,greg@example.com,US 
id,name,email,country 1,Atta Shah,atta@example.com,PK 2,Alex Jones,alex@example.com,DE 3,Jovan Lee,jovan@example.com,FR 4,Greg Hover,greg@example.com,US 

There are multiple ways to read a CSV file with OpenCSV. You can choose to read the CSV file either line-by-line or at once. Similarly, you can decide whether to read the record as a string array or bind the record into an object. Let us look at all these approaches below.

The simplest way to read a CSV file using OpenCSV is by reading each record into a string array. Here is an example that uses the CSVReader class to read one line at a time from the file:

try  // create a reader Reader reader = Files.newBufferedReader(Paths.get("users.csv")); // create csv reader CSVReader csvReader = new CSVReader(reader); // read one record at a time String[] record; while ((record = csvReader.readNext()) != null)  System.out.println("ID: " + record[0]); System.out.println("Name: " + record[1]); System.out.println("Email: " + record[2]); System.out.println("Country: " + record[3]); > // close readers csvReader.close(); reader.close(); > catch (IOException ex)  ex.printStackTrace(); > 

Reading all records at once

In the example above, the readNext() method reads the next line from the buffer and converts it to a string array. The CSVReader class also provides a method called readAll() that reads the entire file into a List with each element being a String[] of tokens:

try  // create a reader Reader reader = Files.newBufferedReader(Paths.get("users.csv")); // create csv reader CSVReader csvReader = new CSVReader(reader); // read all records at once ListString[]> records = csvReader.readAll(); // iterate through the list of records for (String[] record : records)  System.out.println("ID: " + record[0]); System.out.println("Name: " + record[1]); System.out.println("Email: " + record[2]); System.out.println("Country: " + record[3]); > // close readers csvReader.close(); reader.close(); > catch (IOException ex)  ex.printStackTrace(); > 

The above approach is not recommended for larger CSV files as it loads the entire file contents into memory.

Skipping the header

There is no way to skip the header record when using the CSVReader class. If you read a file that contains a header, then the header will also be printed on the console. Instead, you should use CSVReaderBuilder , which provides greater flexibility and more configuration options, including the ability to skip the header record. Let us use the CSVReaderBuilder class to create a CSVReader object with a specified number of records skipped:

CSVReader csvReader = new CSVReaderBuilder(reader).withSkipLines(1).build(); 

CSVParserBuilder allows you to choose a custom column separator, ignore or handle quotations marks, decide what to do with null fields, and how to interpret escaped characters:

CSVParser parser = new CSVParserBuilder() .withSeparator('\t') .withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_QUOTES) .withIgnoreLeadingWhiteSpace(true) .withIgnoreQuotations(false) .withStrictQuotes(true) .build(); CSVReader csvReader = new CSVReaderBuilder(reader) .withSkipLines(1) .withCSVParser(parser) .build(); 

The real benefit of using OpenCSV is that you can directly map the record fields into a Java object. There are two ways of doing this. You can use annotations or mapping strategies to bind the record fields to bean attributes. OpenCSV has two types of annotations to specify the column names mapping with object fields either by name or by position: @CsvBindByName and @CsvBindByPosition .

Using @CsvBindByName annotation

You can only use the @CsvBindByName annotation if the CSV file has a header. It accepts up to five parameters, including column , required , and locale . All parameters are options except column , which is also only required if the header column name in the CSV file is different from the bean field. Let us first create a Java class to make use of the CsvBindByName annotation: User.java

public class User  @CsvBindByName public int id; @CsvBindByName public String name; @CsvBindByName public String email; @CsvBindByName(column = "country") public String countryCode; // getters and setters omitted for brevity > 

Here is an example that reads and parses the CSV file records directly into Java objects using OpenCSV:

try  // create a reader Reader reader = Files.newBufferedReader(Paths.get("users-with-header.csv")); // create csv bean reader CsvToBean csvToBean = new CsvToBeanBuilder(reader) .withType(User.class) .withIgnoreLeadingWhiteSpace(true) .build(); // iterate through users for (User user : (IterableUser>) csvToBean)  System.out.println("ID: " + user.getId()); System.out.println("Name: " + user.getName()); System.out.println("Email: " + user.getEmail()); System.out.println("Country: " + user.getCountryCode()); > // close the reader reader.close(); > catch (IOException ex)  ex.printStackTrace(); > 

Note that we used the users-with-headers.csv file for the above example because it contains a header. The CsvToBean class also provides a parse() method that reads entire CSV file contents into memory and then parses it into a list of objects (not recommended for large CSV files):

ListUser> users = csvToBean.parse(); // iterate through list for (User user : users)  System.out.println("ID: " + user.getId()); System.out.println("Name: " + user.getName()); System.out.println("Email: " + user.getEmail()); System.out.println("Country: " + user.getCountryCode()); > 

Using @CsvBindByPosition annotation

If the CSV file does not have a header, you use the @CsvBindByPosition annotation to map the column position (zero-based) to bean fields like the below:

public class User  @CsvBindByPosition(position = 0) public int id; @CsvBindByPosition(position = 1) public String name; @CsvBindByPosition(position = 2) public String email; @CsvBindByPosition(position = 3) public String countryCode; // getters and setters omitted for brevity > 

Mapping strategies are another way of mapping the CSV columns directly to Java object fields. Using this strategy, you can safely remove all OpenCSV annotations from your Java classes. Let us first remove all annotations from the User class:

public class User  public int id; public String name; public String email; public String countryCode; public User(int id, String name, String email, String countryCode)  this.id = id; this.name = name; this.email = email; this.countryCode = countryCode; > // getters and setters omitted for brevity > 

Now let us use ColumnPositionMappingStrategy to specify the mapping between CSV columns and Java object attributes and then parse the CSV records into Java objects:

try  // create a reader Reader reader = Files.newBufferedReader(Paths.get("users-with-header.csv")); // columns name String[] columns = "id", "name", "email", "countryCode">; // create a mapping strategy ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy(); strategy.setType(User.class); strategy.setColumnMapping(columns); // create csv bean reader CsvToBean csvToBean = new CsvToBeanBuilder(reader) .withMappingStrategy(strategy) .withSkipLines(1) .withIgnoreLeadingWhiteSpace(true) .build(); // iterate through users for (User user : (IterableUser>) csvToBean)  System.out.println("ID: " + user.getId()); System.out.println("Name: " + user.getName()); System.out.println("Email: " + user.getEmail()); System.out.println("Country: " + user.getCountryCode()); > // close the reader reader.close(); > catch (IOException ex)  ex.printStackTrace(); > 

The ColumnPositionMappingStrategy class uses the position of the column in the CSV file to map it to the bean attribute.

OpenCSV allows you to generate a CSV file from an array of strings or from a list of objects. It has more configuration options than Commons CSV for writing data to CSV files. Most importantly, you can easily convert any list of objects to a CSV file by writing just a few lines of code.

try  // create a write Writer writer = Files.newBufferedWriter(Paths.get("users-simple.csv")); // header record String[] headerRecord = "id", "name", "email", "country">; // create a csv writer ICSVWriter csvWriter = new CSVWriterBuilder(writer) .withSeparator(CSVWriter.DEFAULT_SEPARATOR) .withQuoteChar(CSVWriter.NO_QUOTE_CHARACTER) .withEscapeChar(CSVWriter.DEFAULT_ESCAPE_CHARACTER) .withLineEnd(CSVWriter.DEFAULT_LINE_END) .build(); // write header record csvWriter.writeNext(headerRecord); // write data records csvWriter.writeNext(new String[] "1", "Emma Watson", "emma.watson@example.com", "UK">); csvWriter.writeNext(new String[] "2", "Nick Jones", "nick.jones@example.com", "DE">); csvWriter.writeNext(new String[] "3", "Shanzay Alai", "shanzay.alai@example.com", "US">); // close writers csvWriter.close(); writer.close(); > catch (IOException ex)  ex.printStackTrace(); > 

Here is an example that shows how to convert a list of objects into a CSV file. It is using the User class we defined in the previous example:

try  // create a write Writer writer = Files.newBufferedWriter(Paths.get("users-objects.csv")); // create a csv writer StatefulBeanToCsvUser> csvWriter = new StatefulBeanToCsvBuilderUser>(writer) .withSeparator(CSVWriter.DEFAULT_SEPARATOR) .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) .withEscapechar(CSVWriter.DEFAULT_ESCAPE_CHARACTER) .withLineEnd(CSVWriter.DEFAULT_LINE_END) .withOrderedResults(false) .build(); // create a list of objects (`User`) ListUser> users = new ArrayList>(); users.add(new User(1, "Emma Watson", "emma.watson@example.com", "UK")); users.add(new User(2, "Nick Jones", "nick.jones@example.com", "DE")); users.add(new User(3, "Shanzay Alai", "shanzay.alai@example.com", "US")); // write a list of objects csvWriter.write(users); // close the writer writer.close(); > catch (Exception ex)  ex.printStackTrace(); > 

That is all for reading and writing CSV files in Java using the OpenCSV library. We discussed almost all ways to write and read data from a CSV file. OpenCSV is a simple yet very powerful CSV parser that makes it a popular choice for manipulating CSV files in Java. I appreciate your patience in reading this long article.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.

You might also like.

Источник

Читайте также:  Метод решето эратосфена питон
Оцените статью