OpenCSV: How to create CSV file from POJO with custom column headers and custom column positions?

后端 未结 19 1495
温柔的废话
温柔的废话 2020-12-08 04:14

I have created a MappingsBean class where all the columns of the CSV file are specified. Next I parse XML files and create a list of mappingbeans. Then I write that data int

19条回答
  •  南笙
    南笙 (楼主)
    2020-12-08 04:57

    There is another version for 5.2 version because I have a problem with @CsvCustomBindByName annotation when I tried answers above.

    I defined custom annotation :

    @Target(ElementType.FIELD)
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CsvPosition {
    
      int position();
    }
    
    

    and custom mapping strategy

    public class CustomMappingStrategy extends HeaderColumnNameMappingStrategy {
    
      private final Field[] fields;
    
      public CustomMappingStrategy(Class clazz) {
        fields = clazz.getDeclaredFields();
        Arrays.sort(fields, (f1, f2) -> {
          CsvPosition position1 = f1.getAnnotation(CsvPosition.class);
          CsvPosition position2 = f2.getAnnotation(CsvPosition.class);
          return Integer.compare(position1.position(), position2.position());
        });
      }
    
      @Override
      public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
        String[] header = new String[fields.length];
        for (Field f : fields) {
          CsvPosition position = f.getAnnotation(CsvPosition.class);
          header[position.position() - 1] = getName(f);
        }
        headerIndex.initializeHeaderIndex(header);
        return header;
      }
    
      private String getName(Field f) {
        CsvBindByName csvBindByName = f.getAnnotation(CsvBindByName.class);
        CsvCustomBindByName csvCustomBindByName = f.getAnnotation(CsvCustomBindByName.class);
        return csvCustomBindByName != null
          ? csvCustomBindByName.column() == null || csvCustomBindByName.column().isEmpty() ? f.getName() : csvCustomBindByName.column()
          : csvBindByName.column() == null || csvBindByName.column().isEmpty() ? f.getName() : csvBindByName.column();
      }
    
    }
    

    My POJO beans are annotated like this

    public class Record {
    
      @CsvBindByName(required = true)
      @CsvPosition(position = 1)
      Long id;
      @CsvCustomBindByName(required = true, converter = BoolanCSVField.class)
      @CsvPosition(position = 2)
      Boolean deleted;
      ...
    }
    

    and final code for writer :

    CustomMappingStrategy mappingStrategy = new CustomMappingStrategy<>(Record.class);
    mappingStrategy.setType(Record.class);
    StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer)
    .withApplyQuotesToAll(false)
    .withOrderedResults(true)
    .withMappingStrategy(mappingStrategy)
    .build();
    

    I hope it will helpful for someone

提交回复
热议问题