如何使用 Java 中的 CsvMapper 将 headers 动态分配给 csv 文件
How to dynamically assign headers to a csv file using CsvMapper in Java
有人可以帮忙吗?
我坚持读取 csv 文件并将其序列化到 POJO 上。
我正在使用 jackson 库中的 CsvMapper。阅读和序列化部分已完成并开始工作 fine-ish。问题是当用户移动 headers/columns 导致序列化做出一些字母顺序假设 CSV 文件上的值也是按字母顺序排列的。
例如(下面的文件第一行有 headers,第二行有人员详细信息值)
personNameHeader,personAgeHeader
Wiliam,32
现在我的POJO如下
@JsonIgnoreProperties(ignoreUnknown = true)
// @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
public class PersonDetailsCSVTemplate {
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
//Public constructor and getters and setters...
这是从 CSV 中读取值并映射到 class
的代码
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
...
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper.typedSchemaFor(PersonDetailsCSVTemplate.class).withHeader();
MappingIterator<PersonDetailsCSVTemplate > dataIterator = csvMapper.readerFor(PersonDetailsCSVTemplate.class).with(schema)
.readValues(data);
while (dataIterator.hasNextValue()) {
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
}
序列化后可以看到CsvMapper映射了如下内容:
PersonDetailsCSVTemplate.name = "32"
和PersonDetailsCSVTemplate.age = "Wiliam"
通过用 @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
注释 class 强制 CSV 始终是名称列后跟年龄列,这并不理想。
任何人都可以提出他们认为可行的任何建议吗?
此致
您可以使用 sortedBy 并为其指定属性在 csv 数据中出现的顺序:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder(value = { "personNameHeader", "personAgeHeader" })
static class PersonDetailsCSVTemplate
{
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getAge()
{
return age;
}
public void setAge(String age)
{
this.age = age;
}
@Override
public String toString()
{
return "PersonDetailsCSVTemplate [name=" + name + ", age=" + age + "]";
}
}
你可以保留或离开@JsonPropertyOrder
它不会影响输出。
@Test
public void sort() throws IOException
{
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.sortedBy("personNameHeader", "personAgeHeader")
.withColumnSeparator(',')
.withComments();
MappingIterator<PersonDetailsCSVTemplate> dataIterator =
csvMapper
.readerFor(PersonDetailsCSVTemplate.class)
.with(schema)
.readValues("personNameHeader,personAgeHeader\r\n"
+
"Wiliam,32\r\n");
while (dataIterator.hasNextValue())
{
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
System.out.println(dataCSV);
}
}
输出:
PersonDetailsCSVTemplate [name=Wiliam, age=32]
从 Jackson 2.7 开始,您可以使用 withColumnReordering(true)
而不是 sortedBy()
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.withColumnReordering(true);
有人可以帮忙吗?
我坚持读取 csv 文件并将其序列化到 POJO 上。
我正在使用 jackson 库中的 CsvMapper。阅读和序列化部分已完成并开始工作 fine-ish。问题是当用户移动 headers/columns 导致序列化做出一些字母顺序假设 CSV 文件上的值也是按字母顺序排列的。
例如(下面的文件第一行有 headers,第二行有人员详细信息值)
personNameHeader,personAgeHeader
Wiliam,32
现在我的POJO如下
@JsonIgnoreProperties(ignoreUnknown = true)
// @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
public class PersonDetailsCSVTemplate {
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
//Public constructor and getters and setters...
这是从 CSV 中读取值并映射到 class
的代码import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
...
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper.typedSchemaFor(PersonDetailsCSVTemplate.class).withHeader();
MappingIterator<PersonDetailsCSVTemplate > dataIterator = csvMapper.readerFor(PersonDetailsCSVTemplate.class).with(schema)
.readValues(data);
while (dataIterator.hasNextValue()) {
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
}
序列化后可以看到CsvMapper映射了如下内容:
PersonDetailsCSVTemplate.name = "32"
和PersonDetailsCSVTemplate.age = "Wiliam"
通过用 @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
注释 class 强制 CSV 始终是名称列后跟年龄列,这并不理想。
任何人都可以提出他们认为可行的任何建议吗? 此致
您可以使用 sortedBy 并为其指定属性在 csv 数据中出现的顺序:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder(value = { "personNameHeader", "personAgeHeader" })
static class PersonDetailsCSVTemplate
{
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getAge()
{
return age;
}
public void setAge(String age)
{
this.age = age;
}
@Override
public String toString()
{
return "PersonDetailsCSVTemplate [name=" + name + ", age=" + age + "]";
}
}
你可以保留或离开@JsonPropertyOrder
它不会影响输出。
@Test
public void sort() throws IOException
{
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.sortedBy("personNameHeader", "personAgeHeader")
.withColumnSeparator(',')
.withComments();
MappingIterator<PersonDetailsCSVTemplate> dataIterator =
csvMapper
.readerFor(PersonDetailsCSVTemplate.class)
.with(schema)
.readValues("personNameHeader,personAgeHeader\r\n"
+
"Wiliam,32\r\n");
while (dataIterator.hasNextValue())
{
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
System.out.println(dataCSV);
}
}
输出:
PersonDetailsCSVTemplate [name=Wiliam, age=32]
从 Jackson 2.7 开始,您可以使用 withColumnReordering(true)
而不是 sortedBy()
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.withColumnReordering(true);