Search code examples
javaapache-commonsapache-commons-csv

Write CSV from List of HashMaps with Header using Apache Commons CSV


I have to take an ArrayList of HashMap and create a CSV using Apache Commons CSV. However, it's not writing the values to the right headers. Is there an easy way to have the library automatically place the values to the right headers using the Enum? I don't want to manually assign it as I will be adding more columns.

This is what it's producing:

enter image description here

Here is what I have:

Header.java

public enum Header
{
    FIRST_NAME(),
    LAST_NAME(),
    GENDER();
}

Main

public static void main(String[] args)
{
    List<Map<Header, String>> output = new ArrayList<>();

    Map<Header, String> map = new HashMap<>();
    map.put(Header.FIRST_NAME, "John");
    map.put(Header.LAST_NAME, "Andrew");
    map.put(Header.GENDER, "Male");
    output.add(map);

    Map<Header, String> map2 = new HashMap<>();
    map2.put(Header.FIRST_NAME, "Sally");
    map2.put(Header.LAST_NAME, "Andrew");
    map2.put(Header.GENDER, "Female");
    output.add(map2);

    String outputFile = System.getProperty("java.io.tmpdir")+"test.csv";

    try (
            BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFile));
            CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
                    .withHeader(Header.class));)
    {
        csvPrinter.printRecords(output);
        csvPrinter.flush();
    } catch (IOException ex)
    {
        Logger.getLogger(TestCSV.class.getName()).log(Level.SEVERE, null, ex);
    }

}

Solution

  • How about this:

    try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFile));
            CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(Header.class));) {
        for (Map<Header, String> row : output) {
            csvPrinter.printRecord(Arrays.asList(Header.values())
                                         .stream()
                                         .map(header -> row.get(header))
                                         .collect(Collectors.toList()));
        }
    } catch (IOException ex) {
        Logger.getLogger(TestCSV.class.getName())
              .log(Level.SEVERE, null, ex);
    }