How to write ArrayList<Object> to a csv file

Maverick picture Maverick · Jan 28, 2016 · Viewed 23.4k times · Source

I have a ArrayList<Metadata> and i want to know if there is a Java API for working with CSV files which has a write method which accepts a ArrayList<> as parameter similar to LinqToCsv in .Net. As i know OpenCSV is available but the CsvWriter class doesn't accept a collection. My Metadata Class is

public class Metadata{
    private String page;
    private String document;
    private String loan;
    private String type;
}
ArrayList<Metadata> record = new ArrayList<Metadata>();

once i populate the record, i want to write each row into a csv file. Please suggest.

Answer

Henrik picture Henrik · Jan 28, 2016

Surely there'll be a heap of APIs that will do this for you, but why not do it yourself for such a simple case? It will save you a dependency, which is a good thing for any project of any size.

Create a toCsvRow() method in Metadata that joins the strings separated by a comma.

public String toCsvRow() {
    return Stream.of(page, document, loan, type)
            .map(value -> value.replaceAll("\"", "\"\""))
            .map(value -> Stream.of("\"", ",").anyMatch(value::contains) ? "\"" + value + "\"" : value)
            .collect(Collectors.joining(","));
}

Collect the result of this method for every Metadata object separated by a new line.

String recordAsCsv = record.stream()
        .map(Metadata::toCsvRow)
        .collect(Collectors.joining(System.getProperty("line.separator")));

EDIT Should you not be so fortunate as to have Java 8 and the Stream API at your disposal, this would be almost as simple using a traditional List.

public String toCsvRow() {
    String csvRow = "";
    for (String value : Arrays.asList(page, document, loan, type)) {
        String processed = value;
        if (value.contains("\"") || value.contains(",")) {
            processed = "\"" + value.replaceAll("\"", "\"\"") + "\"";
        }
        csvRow += "," + processed;
    }
    return csvRow.substring(1);
}