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

后端 未结 19 1462
温柔的废话
温柔的废话 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

    In the latest version the solution of @Sebast26 does no longer work. However the basic is still very good. Here is a working solution with v5.0

    import com.opencsv.bean.BeanField;
    import com.opencsv.bean.ColumnPositionMappingStrategy;
    import com.opencsv.bean.CsvBindByName;
    import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
    import org.apache.commons.lang3.StringUtils;
    
    class CustomMappingStrategy extends ColumnPositionMappingStrategy {
        @Override
        public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
            final int numColumns = getFieldMap().values().size();
            super.generateHeader(bean);
    
            String[] header = new String[numColumns];
    
            BeanField beanField;
            for (int i = 0; i < numColumns; i++) {
                beanField = findField(i);
                String columnHeaderName = extractHeaderName(beanField);
                header[i] = columnHeaderName;
            }
            return header;
        }
    
        private String extractHeaderName(final BeanField beanField) {
            if (beanField == null || beanField.getField() == null || beanField.getField().getDeclaredAnnotationsByType(
                    CsvBindByName.class).length == 0) {
                return StringUtils.EMPTY;
            }
    
            final CsvBindByName bindByNameAnnotation = beanField.getField().getDeclaredAnnotationsByType(CsvBindByName.class)[0];
            return bindByNameAnnotation.column();
        }
    }
    

    And the model looks like this:

    @CsvBindByName(column = "id")
    @CsvBindByPosition(position = 0)
    private Long id;
    @CsvBindByName(column = "name")
    @CsvBindByPosition(position = 1)
    private String name;
    

    And my generation helper looks something like this:

    public static  String createCsv(List data, Class beanClazz) {
        CustomMappingStrategy mappingStrategy = new CustomMappingStrategy();
        mappingStrategy.setType(beanClazz);
    
        StringWriter writer = new StringWriter();
        String csv = "";
        try {
            StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer)
                    .withSeparator(';')
                    .withMappingStrategy(mappingStrategy)
                    .build();
            sbc.write(data);
            csv = writer.toString();
        } catch (CsvRequiredFieldEmptyException e) {
            // TODO add some logging...
        } catch (CsvDataTypeMismatchException e) {
            // TODO add some logging...
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
            }
        }
        return csv;
    }
    

提交回复
热议问题