【问题标题】:Recursive object write to flat csv file递归对象写入平面 csv 文件
【发布时间】:2020-03-01 13:28:07
【问题描述】:

我需要写这样的对象

class User {
    UUID id;
    String name;
    Role role;
}

class Role {
    String name;
    LocalDate activeFrom;
    Authority owner;
}

class Authority {
    String name;
}

棘手的想法是 csv 写入应该通过对象树递归地工作。还需要将 LocalDate 写为像 2019-11-05 f.e. 这样的字符串;

生成的 csv 文件应该是扁平的,看起来像:

user.id,user.name,user.role.name,user.role.activeFrom,user.role.owner.name

// 示例值


我已经尝试过 OpenCsv:

        StatefulBeanToCsv<User> beanToCsv = new StatefulBeanToCsvBuilder<User>(printWriter).build();
        try {
            beanToCsv.write(users);
        } catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException e) {
            e.printStackTrace();
        }
        printWriter.close();

和 Univocity 解析器:

CsvWriterSettings settings = new CsvWriterSettings();
        ObjectRowWriterProcessor processor = new ObjectRowWriterProcessor();
        settings.setRowWriterProcessor(processor);
        processor.convertType(User.class, );

到目前为止没有运气。它们只能序列化为 csv 顶级对象。同样在 OpenCsv 中,我在序列化 LocalDate 时遇到了问题。 你能帮助我吗?建议方法或库?

【问题讨论】:

    标签: csv recursion tree hierarchy univocity


    【解决方案1】:

    在 univocity-parsers 上,无需任何映射,您只需使用 @Nested 注释嵌套对象即可。

    class User {
        ...
    
        @Nested
        Role role;
    }
    

    【讨论】:

      【解决方案2】:

      由于我没有得到任何答案,我将描述我的解决方案。 我用过图书馆:

      http://super-csv.github.io/super-csv/index.html

      和扩展:

      https://super-csv.github.io/super-csv/dozer.html

      代码:

      import org.supercsv.io.dozer.CsvDozerBeanWriter;
      import org.supercsv.prefs.CsvPreference;
      import java.io.IOException;
      import java.io.Writer;
      
      static final String[] FIELD_MAPPING = new String[]{
          "user.id", "user.name", "user.role.name", "user.role.activeFrom", "user.role.owner.name"
      };
      
          try (var beanWriter = new CsvDozerBeanWriter(printWriter, CsvPreference.STANDARD_PREFERENCE)) {
              beanWriter.configureBeanMapping(User.class, FIELD_MAPPING);
              beanWriter.writeHeader(FIELD_MAPPING);
              for (User user : users) {
                  beanWriter.write(user);
              }
          }
          printWriter.close();
      

      https://super-csv.github.io/super-csv/xref-test/org/supercsv/example/dozer/Writing.html

      以及如何测试它:

      @Test
      void status_written_in_csv_format() {
          // Setup
          WriteCsvToResponse objectUnderTest = new WriteCsvToResponse ();
          StringWriter stringWriter = new StringWriter();
          PrintWriter printWriter = new PrintWriter(stringWriter);
      
          // Given
          Status status = ...
      
          // When
          objectUnderTest.writeStatus(printWriter, status);
      
          // Then
          String actualCsv = stringWriter.toString();
          assertThat(actualCsv.split("\n"))
             .as("Produced CSV")
             .containsExactly(
               "id,storeId,status",
               "42,142,OK");
      }
      

      How to test a method using a PrintWriter?

      【讨论】:

        猜你喜欢
        • 2020-10-06
        • 1970-01-01
        • 1970-01-01
        • 2018-03-12
        • 2016-01-06
        • 1970-01-01
        • 2018-07-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多