jackson-dataformats-text
jackson-dataformats-text copied to clipboard
Support writing numbers as strings for CSV
It would be nice to have a CSV feature similar to JSON feature JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS
. Enabling of the feature by mapper.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS)
doesn't work for CSV.
I want to write an object of this class:
data class TestData(
val integer: Int,
val float: Float
}
as
"1","1.234"
not as
1,1.234
Interesting... while semantics are slightly different (in CSV output everything is essentially a String), this could be closed enough. The only question I guess would be whether existence of
CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS
would suggest that feature belongs here. And there is the question of how to combine these settings: I suspect addition quoting for numbers should be applied if either of these settings was enabled.
My idea how should it work is as follows:
Given this class
data class TestData(
val integer: Int,
val string: String
}
a) both features are enabled:
mapper.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS)
mapper.enable(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS)
writes
"1","string"
b) only this feature is enabled
mapper.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS)
writes
1,string
So, it wouldn't make any difference in the final output when not set together with ALWAYS_QUOTE_STRINGS
Actually, looking into this bit more I realized that WRITE_NUMBERS_AS_STRINGS
is moving to JsonWriteFeature
(json-specific) and not into StreamWriteFeature
(format-agnostic).
Given this, I think I'd then prefer adding CSV-specific addition, CsvGenerator.Feature.ALWAYS_QUOTE_NUMBERS
.
I think I need this feature. Is there already some work done? If not maybe I can implement it, thankful for any input.
If CsvGenerator.Feature.ALWAYS_QUOTE_NUMBERS
is active, I don't think ALWAYS_QUOTE_STRINGS
should have any influence - in what scenarios would that be useful?
EDIT I just got word my consumers can probably still parse the CSV with "smart" quotes, so I might not need that feature.
@MrBuddyCasino I did not have time to implement this (it was one of top things I'd ideally wanted to have in 2.12 but didn't quite make it), so would be great to get help here. But if not, then maybe someone else has time, would still like this feature either way. :)
As to ALWAYS_QUOTE_STRINGS
, agreed; if ALWAYS_QUOTE_NUMBERS
is enabled, that would mean quoting regardless.
Hi @cowtowncoder, is this issue still up for grabs? This will be my first issue, and I'm interested in working on it.
@achmadafriza yes, this is up for grabs. If you want to work on it, target would be 2.13
branch.
In case somebody comes here after crazy googling like I did: I had the reverse problem - reading in numbers into strings would fail unless I used the now deprecated Feature.WRITE_NUMBERS_AS_STRINGS
I replaced it with CsvMapper.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS)
and it solved my use case.
Hi @cowtowncoder, @achmadafriza I've just switched from OpenCsv to jackson-dataformat-csv because I had multiple issues with it. But I really need this feature which OpenCsv did do: write numbers as strings (with quotes) in CSV. I'm using latest com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.15.2, can't figure out how to do it. Am I missing something, or did it never materialize? The work-around I have now is to replace int & long properties with type BigDecimal, which is cumbersome in building data.
@BertKoor Looking at the discussion, I don't think this was implemented. It would be good to get it done but I'd need help here -- would be happy to get PR merged, help with details.
One thing that is often helpful as a starting point is to create a (failing) test to show how things ought to work, create PR for that.
In this case you'd probably need to add an entry in CsvGenerator.Feature
(since use of JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS
is deprecated.
Decided to go with CsvGenerator.Feature.ALWAYS_QUOTE_NUMBERS
to be explicit, keeping in mind that existing ALWAYS_QUOTE_STRINGS
does NOT apply to numbers yet.