You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Yotam Hadas (Jira)" <ji...@apache.org> on 2022/10/08 09:02:00 UTC

[jira] [Created] (CSV-305) Add data connector

Yotam Hadas created CSV-305:
-------------------------------

             Summary: Add data connector
                 Key: CSV-305
                 URL: https://issues.apache.org/jira/browse/CSV-305
             Project: Commons CSV
          Issue Type: Improvement
            Reporter: Yotam Hadas


After using the csv library I felt like I had 1 main thing missing - something to connect between the "infrastructure" (CSVFormat / CSVPrinter) and the actual data.

Using "setHeader" / "printHeaders" and "printRecord" feels weird:
1. Order matters, when adding more data to the CSV you can easily write values in the wrong column.
2. It will make it easier to understand from the code what the CSV result should look like.

Some kotlin code I wrote to achieve this partially in a project I work on:

Helper classes:


{code:java}
class CSVData() {
    private val columns: MutableList<CSVColumn> = mutableListOf()

    fun getHeaders() = columns.map(CSVColumn::header).toTypedArray()

    fun getRowValues(objectToConvert: Any) = columns.map(CSVColumn::columnValueProvider)
        .map { columnValueProvider -> columnValueProvider.invoke(objectToConvert) }
        .toTypedArray()

    fun addColumn(column: CSVColumn) {
        columns.add(column)
    }
}

data class CSVColumn(val header: String, val columnValueProvider: (T: Any) -> Any?) {code}
How it is used:
{code:java}
val csvData = CSVData() 
csvData.addColumn(CSVColumn("First name"){(it as User).firstName}) csvData.addColumn(CSVColumn("Last name"){(it as User).lastName}) csvData.addColumn(CSVColumn("Payment information type") { (it as User).paymentInformation?.type })

CSVPrinter(
    FileWriter(tempFile),
    CSVFormat.DEFAULT
        .builder()
        .setHeader(
            *csvData.getHeaders()
        ).build()
).use {
    for (user in users) {
        it.printRecord(
            *csvData.getRowValues(user)
        )
    }
    it.flush()
}{code}

What is missing - currently it works with only 1 record type.
A better solution will enable to get the values from multiple objects like:
{code:java}
*csvData.getRowValues(user,userAdditionalDetails) {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)