csv2class
Generic CSV reader/writer with conversion to Scala case class without boilerplate
Table of contents
Goals
- Read and convert CSV files to Scala case classes
- Write Scala case classes to CSV
Getting started
Include dependency:
"com.github.piotr-kalanski" % "csv2class_2.11" % "0.3.3"
or
<dependency>
<groupId>com.github.piotr-kalanski</groupId>
<artifactId>csv2class_2.11</artifactId>
<version>0.3.3</version>
</dependency>
For reading from CSV import:
import com.datawizards.csv2class._
For writing to CSV import:
import com.datawizards.class2csv._
Examples
Reading from CSV
Basic example:
CSV file:
s,i
first,10
second,11
Parsing command:
case class Foo(s: String, i: Int)
parseCSV[Foo]("foo.csv")
result:
Foo("first",10),
Foo("second",11)
Different order of columns
CSV file:
i,s
10,first
11,second
Parsing command:
parseCSV[Foo]("foo.csv")
result:
Foo("first",10),
Foo("second",11)
Returning not parsed rows
CSV file:
s,i
first,10
second,11
third,third
parseCSV[Foo]("foo.csv")
result:
Foo(first,10)
Foo(second,11)
java.lang.NumberFormatException: For input string: "third"
Writing to CSV
case class Foo(s: String, i: Int)
val data = Seq(
Foo("first",10),
Foo("second",11)
)
writeCSV(data, file)
Versioning support
First write below data to CSV:
case class PersonV2(name: String, age: Int, title: Option[String])
val peopleV2 = Seq(
PersonV2("p1", 10, Some("Developer")),
PersonV2("p2", 20, None),
PersonV2("p3", 30, None)
)
writeCSV(peopleV2, file)
Read CSV file with previous version of compatible Person model:
case class Person(name: String, age: Int)
parseCSV[Person](file)
result:
Seq(
Person("p1", 10),
Person("p2", 20),
Person("p3", 30)
)
Read CSV file using newer compatible Person model version - new columns should be Option
type.
case class PersonV3(name: String, age: Int, title: Option[String], salary: Option[Long])
parseCSV[PersonV3](file)
result:
Seq(
PersonV3("p1", 10, Some("Developer"), None),
PersonV3("p2", 20, None, None),
PersonV3("p3", 30, None, None)
)
Complex types
Library supports writing fields with complex types (e.g. case class, Seq) by serializing them usin JSON format.
Example:
case class ClassWithArrayOfStruct(
id: String,
people: Seq[Person]
)
case class Person(name: String, age: Int)
val data = Seq(
ClassWithArrayOfStruct("1",Seq(Person("p1", 10))),
ClassWithArrayOfStruct("2",Seq(Person("p1", 10),Person("p2", 20),Person("p3", 30)))
)
writeCSV(data, file)
result:
id,people
1,"[{""name"":""p1"",""age"":10}]"
2,"[{""name"":""p1"",""age"":10},{""name"":""p2"",""age"":20},{""name"":""p3"",""age"":30}]"
Customizations
Change delimiter
parseCSV[Foo]("file.csv", delimiter = ';')
writeCSV(data, file, delimiter = ';')
CSV without header
parseCSV[Foo]("file.csv", header = false, columns = Seq("s","i"))
writeCSV(data, "file.csv", header = false)