首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Jackson在CSV文件中设置本地化列标题

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

Stack Overflow用户
提问于 2016-02-09 23:36:17
回答 2查看 4.8K关注 0票数 0

我尝试使用jackson-dataformat-csv创建CSV文件,如this tutorial (Jackson Annotation method)中所述。

下面是我的Csv行的定义:

代码语言:javascript
复制
@JsonPropertyOrder(value = {"foo", "bar"})
public class MyDataCsv implements Serializable {
    private String foo;

    private String bar;

    // getter & setter
    //...
}

这就是我如何使用Jackson构建我的CSV:

代码语言:javascript
复制
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中,我得到了这个:

代码语言:javascript
复制
| foo  | bar  |
+------+------+
| foo1 | bar1 |
| foo2 | bar2 |
| foo3 | bar3 |

有没有一种方法可以让列标题不基于属性名称?我的意思是,例如,我如何获得带有本地化标签的CSV:

代码语言:javascript
复制
| ProperLabel_EN | ProperLabel2_EN |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |

或者用法语

代码语言:javascript
复制
| ProperLabel_FR | ProperLabel2_FR |
+----------------+-----------------+
| foo1           | bar1            |
| foo2           | bar2            |
| foo3           | bar3            |

干杯

EN

回答 2

Stack Overflow用户

发布于 2017-08-24 17:10:56

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

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

这就是为什么我为CsvSchema手动添加了经过翻译后的头文件。

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

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

代码语言:javascript
复制
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;
}

}

然后,在定义映射器时:

代码语言:javascript
复制
csvMapper = new CsvMapper();
csvMapper.setPropertyNamingStrategy(new LocalizedPropertyNamingStrategy(messageSource, locale));
票数 4
EN

Stack Overflow用户

发布于 2016-02-10 00:07:47

你有没有试过使用

@JsonProperty("ProperLabel")

私有字符串foo;

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35295997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档