如何在JacksonCsvMapper中替换每个逗号的小数点?

jgovgodb  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(131)

我有这个问题,现在我没有找到任何解决方案。我正在使用Jackson库通过Sping Boot 端点生成CSV文件。除了小数点分隔符,一切都正常。默认情况下,它使用点(.),但在我的国家小数点分隔符是逗号(,),应该使用该字符导出。
我在Jackson文档中搜索,但没有看到任何类似setDecimalSeparator或类似的东西。另一个尝试是替换我要导出为String的类中的Double字段,但在这种情况下,导出也会在这些字段上添加双引号。
下面是我创建的用于生成CSV的代码:

ObjectMapper map = new ObjectMapper();
byte[] data = map.writerWithDefaultPrettyPrinter().writeValueAsBytes(responseObject);
byte[] dataCsv;
if (data.length != 3) {
    JsonNode jsonTree = new ObjectMapper().readTree(data);

    CsvSchema.Builder csvSchemaBuilder = CsvSchema.builder();
    JsonNode firstObject = jsonTree.elements().next();
    firstObject.fieldNames().forEachRemaining(fieldName -> {
        csvSchemaBuilder.addColumn(fieldName);
    });

    CsvSchema csvSchema = csvSchemaBuilder.build().withHeader().withColumnSeparator(';');

    CsvMapper csvMapper = new CsvMapper();
    dataCsv = csvMapper.writerFor(JsonNode.class).with(csvSchema).writeValueAsBytes(jsonTree);
} else {
    throw new ResponseNoResultsException();
}

HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Expose-Headers", "Content-Disposition");
headers.add("Content-Disposition", "attachment; filename=\"" + filename + ".csv\"");
headers.add("X-Frame-Options", "DENY");
headers.add("Content-Security-Policy", "default-src: 'self'; script-src: 'self' static.domain.tld");
headers.add("Strict-Transport-Security", "max-age=31536000;");
headers.add("X-Content-Type-Options", "nosniff");

return ResponseEntity
        .ok()
        .contentLength(dataCsv.length)
        .contentType(
                MediaType.parseMediaType("application/octet-stream"))
        .headers(headers)
        .body(new InputStreamResource(new ByteArrayInputStream(dataCsv)));

字符串
我以CSV形式返回的类如下所示:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonPropertyOrder({
        "field1",
        "field2",
        "field3",
        "field4",
        
})
public class ExampleQuestionClass {
    @JsonProperty("field1")
    private String field1;
    @JsonProperty("field2")
    private String field2;
    @JsonProperty("field3")
    private Double field3;
    @JsonProperty("field4")
    private Double field4;
}


最后的CSV应该是这样的:

field1;field2;field3;field4;
"Value 1";"Value, 2";7,1;8,0;


你能帮我吗?

5vf7fwbs

5vf7fwbs1#

我们可以定制双字段的序列化。
1.实施自定义优化器
1.使用JsonDeserializer注解字段

public static class CustomDoubleSerializer extends StdSerializer<Double> {

    public CustomDoubleSerializer() {
        this(null);
    }

    public CustomDoubleSerializer(Class<Double> cls) {
        super(cls);
    }

    @Override
    public void serialize(Double value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // German using , instead of . to separate decimal
        NumberFormat instance = NumberFormat.getInstance(Locale.GERMAN);
        instance.setMinimumFractionDigits(1);
        gen.writeString(instance.format(value));
    }
}

字符串
注解类,如

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonPropertyOrder({
        "field1",
        "field2",
        "field3",
        "field4",

})
public class ExampleQuestionClass {
    @JsonProperty("field1")
    private String field1;
    @JsonProperty("field2")
    private String field2;
    @JsonSerialize(using = CustomDoubleSerializer.class)
    @JsonProperty("field3")
    private Double field3;
    @JsonSerialize(using = CustomDoubleSerializer.class)
    @JsonProperty("field4")
    private Double field4;
}


试试下面的主要方法

public static void main(String[] args) throws IOException {
    ObjectMapper map = new ObjectMapper();
    byte[] data = map.writerWithDefaultPrettyPrinter().writeValueAsBytes(List.of(new ExampleQuestionClass("Value 1", "Value, 2", 7.1, 8.0)));
    if (data.length != 3) {
        JsonNode jsonTree = new ObjectMapper().readTree(data);

        CsvSchema.Builder csvSchemaBuilder = CsvSchema.builder();
        JsonNode firstObject = jsonTree.elements().next();
        firstObject.fieldNames().forEachRemaining(csvSchemaBuilder::addColumn);

        CsvSchema csvSchema = csvSchemaBuilder.build().withHeader().withColumnSeparator(';');
        CsvMapper csvMapper = new CsvMapper();
        System.out.println(csvMapper.writerFor(JsonNode.class).with(csvSchema).writeValueAsString(jsonTree));
    }
}


应显示

"field1";"field2";"field3";"field4"
"Value 1";"Value, 2";"7,1";"8,0"

相关问题