2016-02-09 37 views
0

我嘗試使用jackson-dataformat-csv創建一個CSV文件,如this tutorial(Jackson註解方法)中所述。使用Jackson在CSV文件中設置本地化的列標題

這裏是我的CSV行的定義:

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

    private String bar; 

    // getter & setter 
    //... 
} 

這是我建立我的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   | 

乾杯

回答

1

您是否嘗試過使用

@JsonProperty(」 ProperLabel「)
private String foo;

+0

謝謝事實上它的工作原理。但正如我提到你的答案後:),我怎麼能得到相同的,但與本地化的標題列(例如法國「BonLibellé」和英文「ProperLabel」)?我不能使用@JsonProperty(「ProperLabel」),我可以嗎? – Tako

2

這是一個遲到的回答抱歉。 我發現這個問題的方式有點棘手。

基本上,csvMapper期望標頭和屬性名稱完全相同,否則它無法檢測並映射相關標頭的屬性值。

這就是爲什麼我手動添加標題與他們的翻譯形式的CsvSchema。

然後爲了操縱屬性名稱,我創建了一個自定義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)); 
相關問題