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

标签 java csv internationalization jackson

我尝试使用 jackson-dataformat-csv 创建 CSV 文件,如 this tutorial 中所述。 ( 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 中,我得到这个:

| foo  | bar  |
+------+------+
| foo1 | bar1 |
| foo2 | bar2 |
| foo3 | bar3 |

有没有办法让列标题不基于属性名称?我的意思是,我怎样才能获得带有本地化标签的 CSV :

| ProperLabel_EN | ProperLabel2_EN |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |

或者法语

| ProperLabel_FR | ProperLabel2_FR |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |

干杯

最佳答案

很抱歉,这个答案迟到了。 我发现这个问题的方法有点棘手。

基本上,csvMapper 期望 header 和属性名称完全相同,否则它无法检测属性值并将其映射到相关 header 。

这就是为什么我为 CsvSchema 手动添加 header 及其翻译形式。

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

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

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 = new CsvMapper();
csvMapper.setPropertyNamingStrategy(new LocalizedPropertyNamingStrategy(messageSource, locale));

关于java - 使用 Jackson 在 CSV 文件中设置本地化列标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35295997/

相关文章:

java - 相同的条件逻辑为 Java 中的 AtomicBoolean 生成两个截然不同的字节码。为什么?

php - 将查询导出为 csv 需要改进

git - git 是否可以显示带有重音符号的文件名?

java - hibernate 错误 : There is no primary key for referenced table

java - 制作二叉搜索树会引发异常

java - 从 ActionListener 内部的 JOptionPane 初始化字符串

java - 将时间和日期转换为相对时间(CSV 处理)

Ruby:无法解析在 OS X 中导出为 CSV 的 Excel 文件

localization - 可以在Stripe中使用非英语文本吗?

python - 我可以同时调用和设置库中的 Python gettext 模块和使用它的模块吗?