Работа с CSV в Kotlin: библиотеки и практические примеры
Формат CSV (Comma-Separated Values) остаётся одним из самых популярных способов обмена табличными данными. В языке Kotlin, который активно используется для разработки под Android, бэкенда (Ktor, Spring Boot) и скриптов, существует несколько удобных библиотек для работы с CSV. В этой статье мы разберём три основных подхода: лёгкую библиотеку kotlin-csv, мощный OpenCSV и классический Apache Commons CSV.
1. Библиотека kotlin-csv (рекомендуется)
Это чисто Kotlin-решение, которое не требует дополнительных зависимостей на Java. Оно идеально подходит для проектов, где важна лаконичность и безопасность типов.
Установка (Gradle)
// build.gradle.kts
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.9.3")
Чтение CSV
Библиотека поддерживает автоматическое определение разделителя, экранирование кавычек и заголовки.
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
fun readCsvExample() {
val csvData = """
name,age,city
Alice,30,New York
Bob,25,London
""".trimIndent()
val rows: List<List<String>> = csvReader().readAll(csvData)
rows.forEach { row ->
println("Name: ${row[0]}, Age: ${row[1]}, City: ${row[2]}")
}
}
// Чтение с заголовками
fun readWithHeaders() {
val data = csvReader().readAllWithHeader(csvData)
data.forEach { row ->
println("${row["name"]} is ${row["age"]} years old")
}
}
Запись CSV
import com.github.doyaaaaaken.kotlincsv.dsl.csvWriter
fun writeCsvExample() {
val rows = listOf(
listOf("Product", "Price", "Quantity"),
listOf("Laptop", "1200", "5"),
listOf("Mouse", "25", "50")
)
csvWriter().writeAll(rows)
// Вывод в консоль:
// Product,Price,Quantity
// Laptop,1200,5
// Mouse,25,50
}
2. OpenCSV (для сложных сценариев)
OpenCSV — зрелая Java-библиотека, которая отлично работает в Kotlin. Она поддерживает маппинг в data-классы, кастомные разделители и потоковую обработку больших файлов.
Установка
implementation("com.opencsv:opencsv:5.9")
Чтение с маппингом в data-класс
import com.opencsv.bean.CsvToBeanBuilder
import java.io.StringReader
data class Person(
@CsvBindByName(column = "name")
val name: String,
@CsvBindByName(column = "age")
val age: Int,
@CsvBindByName(column = "city")
val city: String
)
fun readWithOpenCsv() {
val csv = """
name,age,city
Alice,30,New York
Bob,25,London
""".trimIndent()
val beans: List<Person> = CsvToBeanBuilder<Person>(StringReader(csv))
.withType(Person::class.java)
.build()
.parse()
beans.forEach { println(it) }
// Person(name=Alice, age=30, city=New York)
// Person(name=Bob, age=25, city=London)
}
Запись с заголовками
import com.opencsv.bean.StatefulBeanToCsv
import com.opencsv.bean.StatefulBeanToCsvBuilder
import java.io.StringWriter
fun writeWithOpenCsv() {
val people = listOf(
Person("Charlie", 35, "Paris"),
Person("Diana", 28, "Tokyo")
)
val writer = StringWriter()
val beanToCsv: StatefulBeanToCsv<Person> = StatefulBeanToCsvBuilder<Person>(writer)
.build()
beanToCsv.write(people)
println(writer.toString())
// name,age,city
// Charlie,35,Paris
// Diana,28,Tokyo
}
3. Apache Commons CSV (для совместимости)
Эта библиотека — стандарт де-факто для Java. Она предоставляет низкоуровневый контроль над парсингом и поддерживает различные форматы (Excel, MySQL, TSV).
Установка
implementation("org.apache.commons:commons-csv:1.11.0")
Чтение с итерацией
import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
import java.io.StringReader
fun readWithCommonsCsv() {
val csv = """
Name,Age,City
Eve,22,Berlin
Frank,40,Moscow