Java 使用Jackson在CSV文件中设置本地化列标题

Java 使用Jackson在CSV文件中设置本地化列标题,java,csv,internationalization,jackson,Java,Csv,Internationalization,Jackson,我尝试使用jackson dataformat CSV创建一个CSV文件,如(jackson注释方法)中所述 以下是我的Csv行的定义: @JsonPropertyOrder(value = {"foo", "bar"}) public class MyDataCsv implements Serializable { private String foo; private String bar; // getter & setter //... }

我尝试使用jackson dataformat CSV创建一个CSV文件,如(jackson注释方法)中所述

以下是我的Csv行的定义:

@JsonPropertyOrder(value = {"foo", "bar"})
public class MyDataCsv implements Serializable {
    private String foo;

    private String bar;

    // getter & setter
    //...
}
这就是我如何使用Jackson构建我的CSV:

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);
}
有没有办法使列标题不基于属性名?我的意思是,例如,如何获得标签本地化的CSV:

| ProperLabel_EN | ProperLabel2_EN |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |
还是用法语

| ProperLabel_FR | ProperLabel2_FR |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |
干杯你试过使用吗

@JsonProperty(“ProperLabel”)
私人字符串foo

你试过使用

@JsonProperty(“ProperLabel”)

私人字符串foo

这是一个迟到的回答,对此表示抱歉。 我发现解决这个问题的方法有点棘手

基本上,csvMapper希望头和属性名称完全相同,否则它无法检测并映射具有相关头的属性值

这就是为什么我为CsvSchema手动添加带有翻译形式的标题

然后,为了操作属性名,我创建了一个自定义属性名称策略

您可以在下面找到代码示例:

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;
}

这是一个迟到的答复,对此表示抱歉。 我发现解决这个问题的方法有点棘手

基本上,csvMapper希望头和属性名称完全相同,否则它无法检测并映射具有相关头的属性值

这就是为什么我为CsvSchema手动添加带有翻译形式的标题

然后,为了操作属性名,我创建了一个自定义属性名称策略

您可以在下面找到代码示例:

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;
}

谢谢,它确实有效。但正如我在你的回答之后提到的:),我如何才能得到同样的标题栏(例如法语中的“BonLibellé”和英语中的“ProperLabel”)?我不能使用
@JsonProperty(“ProperLabel”)
,可以吗?谢谢,它确实有效。但正如我在你的回答之后提到的:),我如何才能得到同样的标题栏(例如法语中的“BonLibellé”和英语中的“ProperLabel”)?我不能使用
@JsonProperty(“ProperLabel”)
,可以吗?
csvMapper = new CsvMapper();
csvMapper.setPropertyNamingStrategy(new LocalizedPropertyNamingStrategy(messageSource, locale));