user12448901
user12448901

Reputation: 25

Why does writing a bean to CSV file fail with OpenCSV (5.6 or 5.7)?

I'm using OpenCSV in version 5.6, and have followed sample https://www.geeksforgeeks.org/mapping-java-beans-to-csv-using-opencsv/ but not able to write mine to csv file.

public static void main(String[] args){
    List<MyPartbean> mybeans = new List<MyPartbean>();
    MyPartbean b1 = new MyPartbean("123", "Red");
    MyPartbean b2 = new MyPartbean("456", "Blue");
    
    mybeans.add(b1);
    mybeans.add(b2);
    
    file_location = "/tmp/out.csv";
    String[] columns = new String[]{"Number", "Description"};
    CSVUtils.writeToCSV(String file_location, MyPartbean.class,
      mybeans, columns)
}

Bean:

public class MyPartbean extends HashMap {
  String number="";
  String description="";
  public MyPartbean(String number, String desc){
     this.number = number;
     this.description = desc;
  }
  public void setNumber(String number){ this.number = number;}
  public void setDescription(String description){ this.description = description;}
  public String getNumber() {return number;}
  public String getDescription() {return description;}
  
}

Write to CSV:

public class CSVUtils {
  public static void writeToCSV(String file_location, Class type,
      List<MyPartbean> records, String[] columns)
      throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {

    FileWriter writer = new FileWriter(file_location);
    ColumnPositionMappingStrategy mappingStrategy = new 
    ColumnPositionMappingStrategy();
    mappingStrategy.setType(type);
    mappingStrategy.setColumnMapping(columns);
    debug("mapping: " +mappingStrategy.getColumnMapping().length);

    StatefulBeanToCsv<MyPartbean> beanToCsv =
        new StatefulBeanToCsvBuilder<MyPartbean>(writer)
            .withMappingStrategy(mappingStrategy)
            . withSeparator(',')
            .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
            .build();
    beanToCsv.write(records);

    for(int i=0; i<records.size(); i++){
      MyPartbean item = (MyPartbean) records.get(i);
      debug(i + " " + item.getNumber() + " :: " + item.getDescription());
    }
    writer.close();
  }
}

Output file has two "," represented by the number of columns[] . But there's no columns and values

,,
,,

Any suggestion?

Upvotes: 1

Views: 469

Answers (1)

MWiesner
MWiesner

Reputation: 9043

It works with OpenCSV 4.x and 5.x (tested for 4.1, 5.6 and 5.7) like so:

Bean

keep it unchanged, as in OP.

Note: I have generalized the writeToCSV method a bit, so it accepts any bean you pass to this method.

Serialize & write

public class CSVUtils {

  public static <T> void writeToCSV(String location, Class<T> type, List<T> records, String[] columns)
          throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {

    ColumnPositionMappingStrategy<T> mappingStrategy = new ColumnPositionMappingStrategy<>();
    mappingStrategy.setType(type);
    mappingStrategy.setColumnMapping(columns);

    try (Writer writer = new FileWriter(file_location)) {
      StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer)
                  .withMappingStrategy(mappingStrategy)
                  .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                  .build();
      beanToCsv.write(records);
    }
  }
}

Runner

public class OpenCSV56Demo {

  public static void main(String[] args){
    List<MyPartbean> mybeans = List.of(new MyPartbean("123", "Red"),
                                       new MyPartbean("456", "Blue"));

    String location = "myPartbeans.csv";
    String[] columns = new String[]{"number", "description"};
    try {
      CSVUtils.writeToCSV(location, MyPartbean.class, mybeans, columns);
    } catch (IOException | CsvRequiredFieldEmptyException | CsvDataTypeMismatchException e) {
      e.printStackTrace();
    }
  }

}

Difference:

  • String[] columns = new String[]{"number", "description"}
  • with lower-cased 'n' and 'd'!

vs.

  • String[] columns = new String[]{"Number", "Description"}; (OP)

Seems, OpenCSV 5.x uses a mapping that does not tolerate upper-cased column names any longer.

Upvotes: 1

Related Questions