It looks like you are printing all the records on the same line .
Other methods like printRecords will be more helpful :
String outputFile = savePath+".csv";
CSVPrinter csvFilePrinter = null;
CSVFormat csvFileFormat = CSVFormat.EXCEL.withHeader();
FileWriter fileWriter = new FileWriter(outputFile);
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
csvFilePrinter.printRecords(excelParser.getRecords());
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
Answer from Arnaud on Stack OverflowIt looks like you are printing all the records on the same line .
Other methods like printRecords will be more helpful :
String outputFile = savePath+".csv";
CSVPrinter csvFilePrinter = null;
CSVFormat csvFileFormat = CSVFormat.EXCEL.withHeader();
FileWriter fileWriter = new FileWriter(outputFile);
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
csvFilePrinter.printRecords(excelParser.getRecords());
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
Automatically close & flush
The Answer by Arnaud is correct and good. Here is a variation, shorter and more modern.
Here we:
- Use the
Path,File, andFilesclasses offered by modern Java NIO.2 to make easier work of file-handling. - Use a
BufferedWriterfor better performance with large amounts of data. - Specify the character encoding to be used. Usually UTF-8 is the best. If you do not understand, read this.
- Include the necessary try-catches for file-related exceptions.
- Add try-with-resources syntax to auto-close the file.
- Skip the explicit flushing, as the buffered writer will be flushed automatically as part of auto-closing the
BufferedWriterandCSVPrinter. To quote the Javadoc, callingjava.io.Writer::close“Closes the stream, flushing it first.”.
Code:
CSVFormat format = CSVFormat.EXCEL.withHeader();
Path path = Paths.get( savePath + ".csv" );
try
(
BufferedWriter writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
CSVPrinter printer = new CSVPrinter( writer , format ) ;
)
{
printer.printRecords( excelParser.getRecords() );
}
catch ( IOException e )
{
e.printStackTrace();
}
// At this point, the `CSVPrinter` is automatically closed.
// And, ➡️ the `BufferedWriter` is automatically closed and flushed.
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:
- Before you begin, ensure the output file is empty or non-existent; OR
- Use the
APPENDoption only on the second and subsequent calls togenerateCSV
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.
Here is one more easy way. After checking file existence only you should instantiate the Writer object else while instantiating file will get created and every time you will get file.exists() as true. If file exists you need to create CSVPrinter with withSkipHeaderRecord() else go with any implementation of header() method. FileWriter constructor takes appendable argument with File parameter. If file is there you have to make the appendable parameter as true.
File file = new File(filePath.concat("/").concat(fileName));
if(file.exists()) {
fileWriter = new FileWriter(file, true);
csvPrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT.withSkipHeaderRecord());
}
else {
fileWriter = new FileWriter(file);
csvPrinter = new CSVPrinter(fileWriter, CSVFormat.DEFAULT.withHeader("FirstName", "LastName", "DOB"));
}