Reputation: 672
I try to create a CSV file using jackson-dataformat-csv as described in this tutorial (Jackson Annotation method).
Here is the definition of my Csv lines :
@JsonPropertyOrder(value = {"foo", "bar"})
public class MyDataCsv implements Serializable {
private String foo;
private String bar;
// getter & setter
//...
}
And this is how I build my CSV using Jackson :
private void generateCsv(OutputStream o, List<MyDataCsv> data) {
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(MyDataCsv.class).withHeader();
ObjectWriter objectWriter = mapper.writer(schema);
objectWriter.writeValue(o, data);
}
In my output CSV I get this :
| foo | bar |
+------+------+
| foo1 | bar1 |
| foo2 | bar2 |
| foo3 | bar3 |
Is there a way to have column title not based on the property name ? I mean, how can I get for example this CSV with the label localized :
| ProperLabel_EN | ProperLabel2_EN |
+----------------+-----------------+
| foo1 | bar1 |
| foo2 | bar2 |
| foo3 | bar3 |
Or in french
| ProperLabel_FR | ProperLabel2_FR |
+----------------+-----------------+
| foo1 | bar1 |
| foo2 | bar2 |
| foo3 | bar3 |
Cheers
Upvotes: 0
Views: 8814
Reputation: 106
It is a late answer sorry for that. The way I found for this problem is a little bit tricky.
Basically, csvMapper expects headers and property names exactly the same, otherwise It can not detect and map property values with related headers.
Thats why I manually added headers with the translated form of them for the CsvSchema.
Then to manipulate the property names I created a custom PropertyNamingStrategy.
Below you can find the code samples :
private CsvSchema prepareCsvSchema(List<CsvHeader> headers, ExportOptions options) {
CsvSchema.Builder builder = CsvSchema.builder();
for (CsvHeader header : headers) {
String localizedHeader = messageSource.getMessage(header.getPropertyKey(), null, options.getLocale());
builder.addColumn(localizedHeader);
}
builder.setUseHeader(true)
.setColumnSeparator(options.getColumnSeparator())
.setArrayElementSeparator(options.getArraySeparator());
return builder.build();
}
public class LocalizedPropertyNamingStrategy extends PropertyNamingStrategy {
private MessageSource messageSource;
private Locale locale;
LocalizedPropertyNamingStrategy(MessageSource messageSource, Locale locale) {
this.messageSource = messageSource;
this.locale = locale;
}
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
return localize(defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return localize(defaultName);
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return localize(defaultName);
}
private String localize(String defaultName) {
final String propertyKey = CsvHeader.getPropertyKeyByFieldName(defaultName);
if (StringUtils.isNotEmpty(propertyKey)) {
return messageSource.getMessage(propertyKey, null, locale);
}
return defaultName;
}
}
And then, while defining the mapper :
csvMapper = new CsvMapper();
csvMapper.setPropertyNamingStrategy(new LocalizedPropertyNamingStrategy(messageSource, locale));
Upvotes: 5
Reputation: 301
Have you tried using
@JsonProperty("ProperLabel")
private String foo;
Upvotes: 2