Search code examples
javaapache-commons-csv

How to append new row using Apache Common CSV CSVPrinter?


I have this class containing a method to generate CSV file using Apache Common CSV library 1.5

public class CSVGenerator {

    private static final String CSV_FILE = "./credentials.csv";
    private static CSVPrinter csvPrinter;

    public static void generateCSV(String FirstName, String LastName, String DOB) {


        try {
            BufferedWriter writer = Files.newBufferedWriter(Paths.get(CSV_FILE) );

            csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
                    .withHeader("FirstName", "LastName", "DOB"));

            csvPrinter.printRecord(FirstName, LastName, DOB);
            csvPrinter.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I have a method in my main class , this method will call the method generateCSV() a couple of times.
How can I write a new row and append it to the existing CSV file ? Using my current implementation, it will keep overwriting my first row.

The more straightforward solution would be to collect all my data in any Java collection (array or list) and then at the very end just iterate the collection and write it to the CSV in one go. But I would not go that way. I prefer to write one row to the CSV , do something else, then call the method again to write a new row and append it to the existing CSV.

Thanks.


Solution

  • Use the APPEND option:

    BufferedWriter writer = Files.newBufferedWriter(
            Paths.get(CSV_FILE), 
            StandardOpenOption.APPEND, 
            StandardOpenOption.CREATE);
    

    You have to set things up so that one of the following is true:

    1. Before you begin, ensure the output file is empty or non-existent; OR
    2. Use the APPEND option only on the second and subsequent calls to generateCSV

    BTW, you are creating a new BufferedWriter and CSVPrinter on each call to generateCSV, and not closing either one. This is wasteful, you should probably create those in the constructor, implement Closeable, and implement a close() method to clean up. Then wrap the calling code in a try-with-resources that instantiates generateCSV.