Priyath Gregory
Priyath Gregory

Reputation: 987

OpenCSV - Map multiple CSV columns to single bean attribute

I have a requirement to,

  1. combine two CSV columns into one bean attribute.
  2. Perform a simple mathematical operation on a column value and map to bean attribute.

Wondering if something like this is possible using OpenCSV annotations.

Input CSV

User ID, First Name, Last Name, Worked Minutes
1234,Jon,Snow,60
1235,Rob,Stark,30

Bean

public class Employee {

  @CsvBindByName(column = "Employee ID")
  private String userId;

  //this should be "First Name, Last Name"
  private String employeeName;

  //this should be Worked Minutes/60
  private String workedHours;

  //getters and setters

}

The only way I have managed to do this is by mapping the columns as it is to separate attributes (userId, firstName, lastName, workedMinutes) and then modifying the employeeName and workedHours getter methods, but I feel like there should be a better way to do this.

Upvotes: 4

Views: 1845

Answers (1)

Algorythmist
Algorythmist

Reputation: 11

I don't know how to do this with OpenCSV, but there is a library I wrote called jflat-core that can handle such complex mappings between objects and flat files.

        CSVReader<Employee> csvReader = CSVReader
                .createWithHeaderMapping(Employee.class,
                        new String[] {"User ID", "First Name", "Last Name", "Worked Minutes"},
                        new String[] {"userId", "firstName", "lastName", "workedHours" });
        //register a special converter for the property workedHours
        csvReader.registerConverter("workedHours",
                minutes -> String.valueOf(Double.valueOf(minutes)/60.0));
        List<Employee> employees = csvReader.readAllWithCallback("employees.csv",
                //The callback can be used to help map attributes from the raw record to the target bean
                (record, employee) -> {
                    String name = String.format("%s %s", record.get("First Name"), record.get("Last Name"));
                    employee.setEmployeeName(name);
                });
        assertEquals(2, employees.size());
        assertEquals("Jon Snow", employees.get(0).getEmployeeName());
        assertEquals("0.5", employees.get(1).getWorkedHours());

Upvotes: 1

Related Questions