Pure Kotlin CSV Reader/Writer.
- easy to setup
- use DSL so easy to read
- in Java, we always need to close file. but it's boilerplate code and not friendly for non-JVM user.
- provide interfaces which automatically close file without being aware.
- kotlin multiplatform project
//gradle kotlin DSL
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.2.0") //for JVM platform
implementation("com.github.doyaaaaaken:kotlin-csv-js:1.2.0") //for Kotlin JS platform
//gradle groovy DSL
implementation 'com.github.doyaaaaaken:kotlin-csv-jvm:1.2.0' //for JVM platform
implementation 'com.github.doyaaaaaken:kotlin-csv-js:1.2.0' //for Kotlin JS platform
<dependency>
<groupId>com.github.doyaaaaaken</groupId>
<artifactId>kotlin-csv-jvm</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.github.doyaaaaaken</groupId>
<artifactId>kotlin-csv-js</artifactId>
<version>1.2.0</version>
</dependency>
@file:DependsOn("com.github.doyaaaaaken:kotlin-csv-jvm:1.2.0") //for JVM platform
@file:DependsOn("com.github.doyaaaaaken:kotlin-csv-js:1.2.0")
//for Kotlin JS platform
You can read csv file from String
, java.io.File
or java.io.InputStream
object.
No need to do any I/O handling. (No need to call use
, close
and flush
method.)
// read from `String`
val csvData: String = "a,b,c\nd,e,f"
val rows: List<List<String>> = csvReader().readAll(csvData)
// read from `java.io.File`
val file: File = File("test.csv")
val rows: List<List<String>> = csvReader().readAll(file)
val csvData: String = "a,b,c\nd,e,f"
val rows: List<Map<String, String>> = csvReader().readAllWithHeader(csvData)
println(rows) //[{a=d, b=e, c=f}]
Sequence
type allows to execute lazily.
It starts to process each rows before reading all row data.
See detail about Sequence
type on Kotlin official document.
csvReader().open("test1.csv") {
readAllAsSequence().forEach { row: List<String> ->
//Do something
println(row) //[a, b, c]
}
}
csvReader().open("test2.csv") {
readAllWithHeaderAsSequence().forEach { row: Map<String, String> ->
//Do something
println(row) //{id=1, name=doyaaaaaken}
}
}
NOTE:readAllAsSequence
and readAllWithHeaderAsSequence
methods can only be called within the open
lambda block.
The input stream is closed after the open
lambda block.
If you want to handle line-by-line, you can do it by using open
method. Use open
method and then use readNext
method inside nested block to read row.
csvReader().open("test.csv") {
readNext()
}
csvReader().openAsync("test.csv") {
val container = mutalbeListOf<List<String>>()
delay(100) //other suspending task
readAllAsSequence().asFlow().collect { row ->
delay(100) // other suspending task
container.add(row)
}
}
Note: openAsync
can be and only be accessed through a coroutine
or another suspending
function
When you create CsvReader, you can choose read options:
// this is tsv reader's option
val tsvReader = csvReader {
charset = "ISO_8859_1"
quoteChar = '"'
delimiter = '\t'
escapeChar = '\\'
}
Opton | default value | description |
---|---|---|
charset | UTF-8 |
Charset encoding. The value must be supported by java.nio.charset.Charset. |
quoteChar | " |
Character used to quote fields. |
delimiter | , |
Character used as delimiter between each field. Use "\t" if reading TSV file. |
escapeChar | " |
Character to escape quote inside field string. Normally, you don't have to change this option. See detail comment on ICsvReaderContext. |
skipEmptyLine | false |
Whether to skip or error out on empty lines. |
skipMissMatchedRow | false |
Whether to skip an invalid row (different number of fields from other rows) or throw an exception. |
autoRenameDuplicateHeaders | false |
Whether to auto rename duplicate headers or throw an exception. |
You can start writing csv in one line, no need to do any I/O handling (No need to call use
, close
and flush
method.):
val rows = listOf(listOf("a", "b", "c"), listOf("d", "e", "f"))
csvWriter().writeAll(rows, "test.csv")
// if you'd append data on the tail of the file, assign `append = true`.
csvWriter().writeAll(rows, "test.csv", append = true)
// You can also write into OutpusStream.
csvWriter().writeAll(rows, File("test.csv").outputStream())
You can also write a csv file line by line by open
method:
val row1 = listOf("a", "b", "c")
val row2 = listOf("d", "e", "f")
csvWriter().open("test.csv") {
writeRow(row1)
writeRow(row2)
writeRow("g", "h", "i")
writeRows(listOf(row1, row2))
}
val rows = listOf(listOf("a", "b", "c"), listOf("d", "e", "f")).asSequence()
csvWriter().openAsync(testFileName) {
delay(100) //other suspending task
rows.asFlow().collect {
delay(100) // other suspending task
writeRow(it)
}
}
If you want to close a file writer manually for performance reasons (e.g. streaming scenario), you can
use openAndGetRawWriter
and get a raw CsvFileWriter
.
DO NOT forget to close
the writer!
val row1 = listOf("a", "b", "c")
@OptIn(KotlinCsvExperimental::class)
val writer = csvWriter().openAndGetRawWriter("test.csv")
writer.writeRow(row1)
writer.close()
When you create a CsvWriter, you can choose write options.
val writer = csvWriter {
charset = "ISO_8859_1"
delimiter = '\t'
nullCode = "NULL"
lineTerminator = "\n"
outputLastLineTerminator = true
quote {
mode = WriteQuoteMode.ALL
char = '\''
}
}
Option | default value | description |
---|---|---|
charset | UTF-8 |
Charset encoding. The value must be supported by java.nio.charset.Charset. |
delimiter | , |
Character used as delimiter between each fields. Use "\t" if reading TSV file. |
nullCode | (empty string) |
Character used when a written field is null value. |
lineTerminator | \r\n |
Character used as line terminator. |
outputLastLineTerminator | true |
Output line break at the end of file or not. |
quote.char | " |
Character to quote each fields. |
quote.mode | CANONICAL |
Quote mode. - CANONICAL : Not quote normally, but quote special characters (quoteChar, delimiter, line feed). This is the specification of CSV.- ALL : Quote all fields.- NON_NUMERIC : Quote non-numeric fields. (ex. 1,"a",2.3) |
Documents
Libraries which use kotlin-csv
- kotlin-grass: Csv File to Kotlin Data Class Parser.
Contributions, issues and feature requests are welcome!
If you have questions, ask away in Kotlin Slack's kotlin-csv
room.
git clone [email protected]:doyaaaaaken/kotlin-csv.git
cd kotlin-csv
./gradlew check
Give a โญ๏ธ if this project helped you!
Copyright ยฉ 2019 doyaaaaaken.
This project is licensed under Apache 2.0.
This project is inspired โค๏ธ by scala-csv
This README was generated with โค๏ธ by readme-md-generator