Search code examples
javacsvopencsv

How to write a column on the same CSV file with OpenCSV, even when the file is empty?


I have to write a code that has to be able to write a column (an array String[] of values) and the header of that column into a CSV file. It has to write the column into an output .csv file in both cases, when it doesn't exist and when there's already a file named as the input value file. Of course I wanna read and write on the same file. Here's the code:

public void afegir_columna_csv(String file, String header, String[] contingut) {
    try {
        FileWriter filewriter = new FileWriter(file, true);
        CSVWriter csvWriter = new CSVWriter(filewriter);
        FileReader filereader = new FileReader(file);
        CSVReader csvReader = new CSVReader(filereader);
        String head = header;
        String[] values = contingut;
        String[] entries = null;
        //Adding the header part:
        String[] H = csvReader.readNext();
        ArrayList listH = new ArrayList(Arrays.asList(H));
        listH.add(head);
        csvWriter.writeNext((String[]) listH.toArray());
        Añadimos los valores:
        int i=0;
        while((entries = csvReader.readNext()) != null) {
            ArrayList list = new ArrayList(Arrays.asList(entries));
            list.add(values[i]);
            csvWriter.writeNext((String[]) list.toArray());
        }
        csvWriter.close();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}

I've been testing the code and that's what happens on both cases: 1.If the file exists but is empty: it doesn't write the first column. 2.If the file already exists and has columns on it: it throws me a cast Exception (where i cast (String[]) list.toArray()).

Any ideas of how it's properly done? Thanks!

Here's the error i get on the testing number 2:

java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap')

Solution

  • After a while analysing the problem i've reached a solution that works. I'm not pretty sure if it's super efficient but it does it's job. Had to change the way i get the information from a file, header and content to only content. Here's the code:

    public void add_column_csv(String[] contingut) {
        try {
            String filename = "output_preproces.csv";
            File _file = new File(filename);
            if(_file.createNewFile()) { //If the file doesn't exists, create and add the first column
                FileWriter filewriter = new FileWriter(filename, true);
                CSVWriter csvWriter = new CSVWriter(filewriter);
                List<String[]> data = new ArrayList<String[]>();
                int i=0;
                while(i < contingut.length) {
                    data.add(new String[] {contingut[i]});
                    i++;
                }
                csvWriter.writeAll(data);
                csvWriter.close();
            }
            else {  //If the file already exists, add a column to it:
                FileReader filereader = new FileReader(filename);
                CSVReader csvReader = new CSVReader(filereader);
                List<String[]> data = new ArrayList<String[]>();
                int i=0;
                while(i < contingut.length) {
                    String[] nextLine;
                    nextLine = csvReader.readNext();
                    String[] aux = new String[nextLine.length + 1];
                    aux[nextLine.length] = contingut[i];
                    int j = 0;
                    while(j < nextLine.length) {aux[j] = nextLine[j]; j++;};
                    data.add(aux);
                    i++;
                }
                csvReader.close();
                new FileWriter(filename, false).close();  //delete the old content of the file
                FileWriter filewriter = new FileWriter(filename, true);
                CSVWriter csvWriter = new CSVWriter(filewriter);
                csvWriter.writeAll(data);
                csvWriter.close();
            }
    
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    

    As you can see, i had to separate the CSVReader from the CSVWriter and save all the data on Lists.