Java - Write CSV File with Apache.commons.csv
Asked Answered
R

3

13

I'm using the apache.commons.csv library in Java. I'm reading a CSV file from a web page with this code:

InputStream input = new URL(url).openStream();
        Reader reader = new InputStreamReader(input, "UTF-8");

        defaultParser = new CSVParser(reader, CSVFormat.DEFAULT);
        excelParser = new CSVParser(reader, CSVFormat.EXCEL.withHeader()); 

        defaultParsedData = defaultParser.getRecords();
        excelParsedData = excelParser.getRecords();

However, I can't find a method in this library to easily write this file to my computer in order to open it up and read from it later on.

I tried this code to save the file.

String outputFile = savePath+".csv";
        CSVPrinter csvFilePrinter = null;
        CSVFormat csvFileFormat = CSVFormat.EXCEL.withHeader();
        FileWriter fileWriter = new FileWriter(outputFile);
        csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);

        for (CSVRecord csvRecord : excelParser) {
            for(String dataPoint: csvRecord){
                csvFilePrinter.print(dataPoint);
            }
            csvFilePrinter.print('\n');
         }

        fileWriter.flush();
        fileWriter.close();
        csvFilePrinter.close();

However, when I try to read the file with this code, nothing prints out:

InputStream input = new FileInputStream(cvsFilePath);
        Reader reader = new InputStreamReader(input, "UTF-8");

        CSVParser load = new CSVParser(reader, CSVFormat.EXCEL);
        //TEST THAT IT WORKED
        java.util.List<CSVRecord> testlist = load.getRecords();
        CSVRecord dataPoint = testlist.get(0);
        System.out.println("print: " + dataPoint.get(0));

This only prints out "print: " If I add

System.out.println("print: " + dataPoint.get(1));

it gives a

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1

When I open the saved CSV file with notepad there is a blank line and then:

2016-03-04,714.98999,716.48999,706.02002,710.890015,1967900,710.890015," ",2016-03-03,718.679993,719.450012,706.02002,712.419983,1956800,712.419983," ",2016-03-02,719.00,720.00,712.00,718.849976,1627800,718.849976,"

Roxy answered 29/3, 2016 at 15:47 Comment(6)
What do you mean by "failed to write the data correctly" ?Inquisitor
@Berger Well, I'm sure I didn't write the code correctly. The file that it saves is not the same file that it read from a webpage. I figured there should be a simple built-in method in Apache Commons to save a file that was in a parser, but I couldn't find one, so I attempted to do it that way.Roxy
Could you show a sample input and the output you get ?Inquisitor
@Berger I get an error "File not loaded completely" when I try to open it in Excel. I updated the OP with the code I'm using to read from the saved file.Roxy
Open it with a simple text editor (notepad, whatever..) and paste the content in your question .Inquisitor
@Berger I added the problems I'm getting when loading the saved file into the program. And I'm about to add what it looks like in notepadRoxy
I
17

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();
Inquisitor answered 29/3, 2016 at 16:15 Comment(0)
S
8

The Answer by Arnaud is correct and good. Here is a variation, shorter and more modern.

Here we:

  • Use the Path, File, and Files classes offered by modern Java to make easier work of file-handling.
  • Use a BufferedWriter for 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 BufferedWriter and CSVPrinter. To quote the Javadoc, calling java.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();
}

Edit: There was a bracket missing.

Sale answered 20/6, 2019 at 5:27 Comment(0)
B
2

Have you tried flushing and closing the CSVPrinter, not the FileWriter?

Bamberger answered 4/1, 2018 at 17:48 Comment(1)
i was not closing the CSVPrinter thank you @ionFreeman.Abjuration

© 2022 - 2024 — McMap. All rights reserved.