In this tutorial, we’re gonna look at Kotlin examples that read and write CSV file using OpenCSV.
Contents
I. Dependency
<dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>1.2.21</version> </dependency> <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>4.0</version> </dependency> |
II. Write Data to CSV File
1. From String Array
var fileWriter = FileWriter("customer.csv") csvWriter = CSVWriter(fileWriter, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END) val data = arrayOf<String>("ID","NAME","ADDRESS","AGE") csvWriter.writeNext(data) |
2. From List of Objects
val customers = Arrays.asList(...) fileWriter = FileWriter("customerList.csv") val mappingStrategy = ColumnPositionMappingStrategy<Customer>() mappingStrategy.setType(Customer::class.java) mappingStrategy.setColumnMapping("id", "name", "address", "age") var beanToCsv = StatefulBeanToCsvBuilder<Customer>(fileWriter) .withMappingStrategy(mappingStrategy) .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) .build() beanToCsv.write(customers) |
3. Practice
– Simple POJO Customer (id, name, address, age):
package com.javasampleapproach.kotlin.opencsv class Customer { var id: String? = null var name: String? = null var address: String? = null var age: Int = 0 constructor() {} constructor(id: String?, name: String?, address: String?, age: Int) { this.id = id this.name = name this.address = address this.age = age } override fun toString(): String { return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]" } } |
– Write to CSV file:
package com.javasampleapproach.kotlin.opencsv import java.io.FileWriter import java.io.IOException import java.util.Arrays import com.opencsv.CSVWriter import com.opencsv.bean.ColumnPositionMappingStrategy import com.opencsv.bean.StatefulBeanToCsv import com.opencsv.bean.StatefulBeanToCsvBuilder private val CSV_HEADER = arrayOf<String>("id", "name", "address", "age") private val customers = Arrays.asList( Customer("1", "Jack Smith", "Massachusetts", 23), Customer("2", "Adam Johnson", "New York", 27), Customer("3", "Katherin Carter", "Washington DC", 26), Customer("4", "Jack London", "Nevada", 33), Customer("5", "Jason Bourne", "California", 36)) fun main(args: Array<String>?) { var fileWriter: FileWriter? = null var csvWriter: CSVWriter? = null var beanToCsv: StatefulBeanToCsv<Customer>? try { fileWriter = FileWriter("customer.csv") // write String Array csvWriter = CSVWriter(fileWriter, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END) csvWriter.writeNext(CSV_HEADER) for (customer in customers) { val data = arrayOf<String>( customer.id!!, customer.name!!, customer.address!!, customer.age.toString()) csvWriter.writeNext(data) } println("Write CSV using CSVWriter successfully!") fileWriter = FileWriter("customerList.csv") // write List of Objects val mappingStrategy = ColumnPositionMappingStrategy<Customer>() mappingStrategy.setType(Customer::class.java) mappingStrategy.setColumnMapping("id", "name", "address", "age") beanToCsv = StatefulBeanToCsvBuilder<Customer>(fileWriter) .withMappingStrategy(mappingStrategy) .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) .build() beanToCsv.write(customers) println("Write CSV using BeanToCsv successfully!") } catch (e: Exception) { println("Writing CSV error!") e.printStackTrace() } finally { try { fileWriter!!.flush() fileWriter.close() csvWriter!!.close() } catch (e: IOException) { println("Flushing/closing error!") e.printStackTrace() } } } |
– Check results:
+ customer.csv
+ customerList.csv
III. Read Data from CSV File
1. As String Array
We have 2 ways:
– Line by line using csvReader.readNext()
– All lines at once using csvReader.readAll()
package com.javasampleapproach.kotlin.opencsv import java.io.BufferedReader import java.io.FileReader import java.io.IOException import com.opencsv.CSVReader import com.opencsv.CSVReaderBuilder fun main(args: Array<String>?) { var fileReader: BufferedReader? = null var csvReader: CSVReader? = null try { println("--- Read line by line ---") fileReader = BufferedReader(FileReader("customer.csv")) csvReader = CSVReader(fileReader) var record: Array<String>? csvReader.readNext() // skip Header record = csvReader.readNext() while (record != null) { println(record[0] + " | " + record[1] + " | " + record[2] + " | " + record[3]) record = csvReader.readNext() } csvReader.close() // ------------------------------------------- println("\n--- Read all at once ---") fileReader = BufferedReader(FileReader("customer.csv")) csvReader = CSVReaderBuilder(fileReader).withSkipLines(1).build() val records = csvReader.readAll() for (_record in records) { println(_record[0] + " | " + _record[1] + " | " + _record[2] + " | " + _record[3]) } } catch (e: Exception) { println("Reading CSV Error!") e.printStackTrace() } finally { try { fileReader!!.close() csvReader!!.close() } catch (e: IOException) { println("Closing fileReader/csvParser Error!") e.printStackTrace() } } } |
– Check result in Console:
--- Read line by line --- 1 | Jack Smith | Massachusetts | 23 2 | Adam Johnson | New York | 27 3 | Katherin Carter | Washington DC | 26 4 | Jack London | Nevada | 33 5 | Jason Bourne | California | 36 --- Read all at once --- 1 | Jack Smith | Massachusetts | 23 2 | Adam Johnson | New York | 27 3 | Katherin Carter | Washington DC | 26 4 | Jack London | Nevada | 33 5 | Jason Bourne | California | 36 |
2. As Java Object using Annotation
– We can use @CsvBindByName
annotation for mapping between the CSV columns and the class fields:
package com.javasampleapproach.kotlin.opencsv import com.opencsv.bean.CsvBindByName class AnnoCustomer { @CsvBindByName var id: String? = null @CsvBindByName var name: String? = null @CsvBindByName var address: String? = null @CsvBindByName var age: Int = 0 constructor() {} constructor(id: String?, name: String?, address: String?, age: Int) { this.id = id this.name = name this.address = address this.age = age } override fun toString(): String { return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]" } } |
– Run the Test Class:
package com.javasampleapproach.kotlin.opencsv import java.io.BufferedReader import java.io.FileReader import java.io.IOException import com.opencsv.bean.CsvToBean import com.opencsv.bean.CsvToBeanBuilder fun main(args: Array<String>?) { var fileReader: BufferedReader? = null var csvToBean: CsvToBean<AnnoCustomer>? try { fileReader = BufferedReader(FileReader("customer.csv")) csvToBean = CsvToBeanBuilder<AnnoCustomer>(fileReader) .withType(AnnoCustomer::class.java) .withIgnoreLeadingWhiteSpace(true) .build() val customers = csvToBean.parse() for (customer in customers) { println(customer) } } catch (e: Exception) { println("Reading CSV Error!") e.printStackTrace() } finally { try { fileReader!!.close() } catch (e: IOException) { println("Closing fileReader/csvParser Error!") e.printStackTrace() } } } |
– Check Result in Console:
Customer [id=1, name=Jack Smith, address=Massachusetts, age=23] Customer [id=2, name=Adam Johnson, address=New York, age=27] Customer [id=3, name=Katherin Carter, address=Washington DC, age=26] Customer [id=4, name=Jack London, address=Nevada, age=33] Customer [id=5, name=Jason Bourne, address=California, age=36] |
3. As simple Java Object
– Simple POJO Customer (id, name, address, age):
package com.javasampleapproach.kotlin.opencsv class Customer { var id: String? = null var name: String? = null var address: String? = null var age: Int = 0 constructor() {} constructor(id: String?, name: String?, address: String?, age: Int) { this.id = id this.name = name this.address = address this.age = age } override fun toString(): String { return "Customer [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]" } } |
– Run the Test Class:
package com.javasampleapproach.kotlin.opencsv import java.io.BufferedReader import java.io.FileReader import java.io.IOException import com.opencsv.bean.ColumnPositionMappingStrategy import com.opencsv.bean.CsvToBean import com.opencsv.bean.CsvToBeanBuilder fun main(args: Array<String>?) { var fileReader: BufferedReader? = null var csvToBean: CsvToBean<Customer>? try { fileReader = BufferedReader(FileReader("customer.csv")) val mappingStrategy = ColumnPositionMappingStrategy<Customer>() mappingStrategy.setType(Customer::class.java) mappingStrategy.setColumnMapping("id", "name", "address", "age") csvToBean = CsvToBeanBuilder<Customer>(fileReader) .withMappingStrategy(mappingStrategy) .withSkipLines(1) .withIgnoreLeadingWhiteSpace(true) .build() val customers = csvToBean.parse() for (customer in customers) { println(customer) } } catch (e: Exception) { println("Reading CSV Error!") e.printStackTrace() } finally { try { fileReader!!.close() } catch (e: IOException) { println("Closing fileReader/csvParser Error!") e.printStackTrace() } } } |
– Check Result in Console:
Customer [id=1, name=Jack Smith, address=Massachusetts, age=23] Customer [id=2, name=Adam Johnson, address=New York, age=27] Customer [id=3, name=Katherin Carter, address=Washington DC, age=26] Customer [id=4, name=Jack London, address=Nevada, age=33] Customer [id=5, name=Jason Bourne, address=California, age=36] |