选择性序列化为CSV,Java

时间:2014-10-24 10:31:58

标签: java csv opencsv supercsv

我正在使用jsefa库来选择性地反序列化csv,例如。 maping只有标题号。 1,3,5我的对象,这工作正常。

现在我想反过来选择性地将我的对象序列化为标题位置1,3,5并且休息位置应该由分号(;)自动分隔。 所以输出看起来像这样:

Header1;Header2;Header3;Header4;Header5;Header6;Header7
bla1;;bla3;;bla5

有人可以建议,如何使用jsefa或任何其他库完成此操作。

1 个答案:

答案 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()或您喜欢的任何内容)并查看它然后应该写中间名字段,而不是忽略它。