我正在使用jsefa库来选择性地反序列化csv,例如。 maping只有标题号。 1,3,5我的对象,这工作正常。
现在我想反过来选择性地将我的对象序列化为标题位置1,3,5并且休息位置应该由分号(;)自动分隔。 所以输出看起来像这样:
Header1;Header2;Header3;Header4;Header5;Header6;Header7
bla1;;bla3;;bla5
有人可以建议,如何使用jsefa或任何其他库完成此操作。
答案 0 :(得分:0)
使用Super CSV无疑是可以实现的。只需在null
数组中提供nameMapping
条目即可始终写入空白列。
private static void writePartial() throws IOException {
Person person1 = new Person("John", "K", "Smith");
Person person2 = new Person("Sally", "T", "Brown");
CsvPreference csvPrefs = new CsvPreference.Builder('"', ';', "\n").build();
String[] nameMapping = new String[] { "firstName", null, "lastName" };
try (ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("output.csv"), csvPrefs)) {
writer.writeHeader("firstName", "middleName", "lastName");
for( Person p : Arrays.asList(person1, person2) ) {
writer.write(p, nameMapping);
}
}
}
您应该获得以下输出:
firstName;middleName;lastName
John;;Smith
Sally;;Brown
这可能是最简单的解决方案,但如果你想要更灵活的东西(你可能想要验证字段值,但从不写它),那么你可以创建一个自定义单元处理器来确保该字段永远不会书面。 只需定义一个总是忽略bean中值的单元格处理器:
public class Ignore extends CellProcessorAdaptor {
@Override
public Object execute(Object value, CsvContext context) {
return null;
}
}
然后使用它:
private static void writePartial() throws IOException {
Person person1 = new Person("John", "K", "Smith");
Person person2 = new Person("Sally", "T", "Brown");
CsvPreference csvPrefs = new CsvPreference.Builder('"', ';', "\n").build();
String[] nameMapping = new String[] { "firstName", "middleName", "lastName" };
CellProcessor[] processors = new CellProcessor[] { new Optional(), new Ignore(), new Optional() };
try (ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("output.csv"), csvPrefs)) {
writer.writeHeader(nameMapping);
for( Person p : Arrays.asList(person1, person2) ) {
writer.write(p, nameMapping, processors);
}
}
}
因此,您可以将它链接在一起new NotNull(new Ignore())
以验证bean的middleName
字段始终具有值,但永远不会写入它。这也意味着如果您稍后改变主意并希望编写该值,则可以将Ignore()
处理器替换为Optional()
(或NotNull()
或您喜欢的任何内容)并查看它然后应该写中间名字段,而不是忽略它。