StatefulBeanToCsv with Column headers

后端 未结 3 1089
长发绾君心
长发绾君心 2021-01-02 04:41

I am using opencsv-4.0 to write a csv file and I need to add column headers in output file.

Here is my code.

public static void buildPro         


        
相关标签:
3条回答
  • 2021-01-02 05:02

    ColumnPositionMappingStrategy#generateHeader returns empty array

    /**
     * This method returns an empty array.
     * The column position mapping strategy assumes that there is no header, and
     * thus it also does not write one, accordingly.
     * @return An empty array
     */
    @Override
    public String[] generateHeader() {
        return new String[0];
    }
    

    If you remove MappingStrategy from BeanToCsv builder

    // replace 
    StatefulBeanToCsv<Product> beanWriter = builder.withMappingStrategy(mappingStrategy).build();
    // with
    StatefulBeanToCsv<Product> beanWriter = builder.build(); 
    

    It will write Product's class members as CSV header

    If your Product class members names are

    "productCode", "MFD", "EXD"
    

    This should be the right solution

    Else, add @CsvBindByName annotation

    import com.opencsv.bean.CsvBindByName;
    import com.opencsv.bean.StatefulBeanToCsv;
    import com.opencsv.bean.StatefulBeanToCsvBuilder;
    
    import java.io.FileWriter;
    import java.io.Writer;
    import java.util.ArrayList;
    import java.util.List;
    
    public class CsvTest {
    
        public static void main(String[] args) throws Exception {
            Writer writer = new FileWriter(fileName);
    
            StatefulBeanToCsvBuilder<Product> builder = new StatefulBeanToCsvBuilder<>(writer);
            StatefulBeanToCsv<Product> beanWriter = builder.build();
    
            List<Product> products = new ArrayList<>();
            products.add(new Product("1", "11", "111"));
            products.add(new Product("2", "22", "222"));
            products.add(new Product("3", "33", "333"));
            beanWriter.write(products);
            writer.close();
        }
    
        public static class Product {
            @CsvBindByName(column = "productCode")
            String id;
            @CsvBindByName(column = "MFD")
            String member2;
            @CsvBindByName(column = "EXD")
            String member3;
    
            Product(String id, String member2, String member3) {
                this.id = id;
                this.member2 = member2;
                this.member3 = member3;
            }
    
            public String getId() {
                return id;
            }
    
            public void setId(String id) {
                this.id = id;
            }
    
            public String getMember2() {
                return member2;
            }
    
            public void setMember2(String member2) {
                this.member2 = member2;
            }
    
            public String getMember3() {
                return member3;
            }
    
            public void setMember3(String member3) {
                this.member3 = member3;
            }
        }
    
    }
    

    Output:

    "EXD","MFD","PRODUCTCODE"

    "111","11","1"

    "222","22","2"

    "333","33","3"

    Pay attention; class, getters & setters needs to be public due to the use of Reflection by OpenCSV library

    0 讨论(0)
  • 2021-01-02 05:16

    I may have missed something obvious here but couldn't you just append your header String to the writer object?

    Writer writer = new FileWriter(filePath);
    writer.append("header1, header2, header3, ...etc \n");
    
    // This will be followed by your code with BeanToCsvBuilder 
    // Note: the terminating \n might differ pending env.
    
    0 讨论(0)
  • 2021-01-02 05:16

    You can append by annotation

    public void export(List<YourObject> list, PrintWriter writer) throws Exception {
            writer.append( buildHeader( YourObject.class ) );
            StatefulBeanToCsvBuilder<YourObject> builder = new StatefulBeanToCsvBuilder<>( writer );
            StatefulBeanToCsv<YourObject> beanWriter = builder.build();
            beanWriter.write( mapper.map( list ) );
            writer.close();
        }
    
        private String buildHeader(Class<YourObject> clazz) {
            return Arrays.stream( clazz.getDeclaredFields() )
                    .filter( f -> f.getAnnotation( CsvBindByPosition.class ) != null
                            && f.getAnnotation( CsvBindByName.class ) != null )
                    .sorted( Comparator.comparing( f -> f.getAnnotation( CsvBindByPosition.class ).position() ) )
                    .map( f -> f.getAnnotation( CsvBindByName.class ).column() )
                    .collect( Collectors.joining( "," ) ) + "\n";
        }
    
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    public class YourObject {
    
        @CsvBindByPosition(position = 0)
        @CsvBindByName(column = "A")
        private Long a;
    
        @CsvBindByPosition(position = 1)
        @CsvBindByName(column = "B")
        private String b;
    
        @CsvBindByPosition(position = 2)
        @CsvBindByName(column = "C")
        private String c;
    
    }
    
    0 讨论(0)
提交回复
热议问题