-1

I am trying to export content of a JTable to a .csv file. I tried some code, there is no error but the file I intended to write does not get written. Could anyone see why? Thanks

public static boolean exportToCSV(JTable resultsTable) {
   try {

    TableModel model = resultsTable.getModel();
    FileWriter csv = new FileWriter(new File("/tmp/export.csv"));

    for (int i = 0; i < model.getColumnCount(); i++) {
        csv.write(model.getColumnName(i) + ",");
    }

    csv.write("\n");

    for (int i = 0; i < model.getRowCount(); i++) {
        for (int j = 0; j < model.getColumnCount(); j++) {
            csv.write(model.getValueAt(i, j).toString() + ",");
        }
        csv.write("\n");
    }

    csv.close();
    return true;
   } catch (IOException e) {
    e.printStackTrace();
   }
   return false;
}
3
  • Search Stack Overflow before posting. Writing to files, and writing CSV, has been covered many times, with fully working code examples for you to follow. Tip: Use a library such as Apache Commons CSV. Commented Jun 19, 2019 at 21:22
  • Do you receive any error messages? It also looks like you're writing to /tmp, from my understanding there is no guarantee that files in /tmp will stick around for long. Commented Jun 19, 2019 at 21:29
  • If you can, you should always use an external library for creating csv files (because you would need to escape certain characters). However, it seems that in this case you are having trouble writing to the file, which is not csv related Commented Jun 19, 2019 at 21:43

2 Answers 2

1

Practice with a simple file

Take baby steps. First, be sure you are opening a file successfully.

Modern Java offers the Path, File, and Files classes to make handling files on storage much easier.

Example:

package work.basil.example;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Csver
{
    public static void main ( String[] args )
    {
        Csver app = new Csver() ;
        app.writeDummyFile() ;
    }

    private void writeDummyFile ()
    {
        Path path = Paths.get( "/Users/basilbourque/dummy.txt" ) ;
        // Use try-with-resources to auto-close the file if successfully opened.
        try ( 
            BufferedWriter writer = Files.newBufferedWriter( path ) ;  // Will be automatically closed if successfully opened.
        )
        {
            writer.write( "Bonjour le monde!" ) ;
        } catch ( IOException e )
        {
            e.printStackTrace() ;
        }
    }

}

Use a library for CSV

Next, for CSV or Tab-delimited files or such, use a library. I use Apache Commons CSV. Search Stack Overflow for many examples of using this and other such libraries to read and write these kinds of files.

Use CSVFormat to define the type of file. Here we use standard CSV as defined by RFC 4180. Note that standard CSV uses CRLF (CARRIAGE RETURN LINE FEED) to denote line breaks rather then LF (LINE FEED) seen commonly in Unix-like platforms.

When opening the file, we specify UTF-8 character encoding. UTF-8 is generally the best encoding to use; it covers all the Unicode characters, and is a superset of US-ASCII.

The CSVPrinter::print method adds a field at a time when outputting a row. We terminate the row by calling CSVPrinter::println.

I renamed your i & j variables to be meaningful.

I added column names at the top of the file. You may want to keep or discard that feature, up to you.

Notice how we are using try-with-resources syntax to auto-close our file.

package work.basil.example;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;

import javax.swing.*;
import javax.swing.table.TableModel;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Csver
{
    public static void main ( String[] args )
    {
        Csver app = new Csver();

        // Practice writing a simple file.
        app.writeDummyFile();

        // Write out the data in a JTable to standard CSV file.
        JTable jtable = app.newJTable();
        app.writeCSV( jtable.getModel() );

        System.out.println( "« fin »" );
    }

    private void writeCSV ( final TableModel model )
    {
        CSVFormat format = CSVFormat.RFC4180;
        Path path = Paths.get( "/Users/basilbourque/animals.csv" );
        try (
                BufferedWriter writer = Files.newBufferedWriter( path , StandardCharsets.UTF_8 ) ;
                CSVPrinter printer = new CSVPrinter( writer , format ) ;
        )
        {
            // Print column headers, if you want.
            for ( int columnIndex = 0 ; columnIndex < model.getColumnCount() ; columnIndex++ )
            {
                printer.print( model.getColumnName( columnIndex ) );
            }
            printer.println();

            // Print rows.
            for ( int rowIndex = 0 ; rowIndex < model.getRowCount() ; rowIndex++ )
            {
                for ( int columnIndex = 0 ; columnIndex < model.getColumnCount() ; columnIndex++ )
                {
                    printer.print( model.getValueAt( rowIndex , columnIndex ) );
                }
                printer.println();
            }
        } catch ( IOException e )
        {
            e.printStackTrace();
        }
    }

    private JTable newJTable ()
    {
        String[] columnNames = { "Species" , "Name" };
        Object[][] data = {
                { "Dog" , "Delilah" } ,
                { "Cat" , "René" } ,
                { "Bird" , "Jordan" }
        };
        JTable table = new JTable( data , columnNames );
        return table;
    }

    private void writeDummyFile ()
    {
        Path path = Paths.get( "/Users/basilbourque/dummy.txt" );
        // Use try-with-resources to auto-close the file if successfully opened.
        try ( BufferedWriter writer = Files.newBufferedWriter( path ) )
        {
            writer.write( "Bonjour le monde!" );
        } catch ( IOException e )
        {
            e.printStackTrace();
        }
    }

}
Sign up to request clarification or add additional context in comments.

3 Comments

could I do all that in one method?
@petelam Also, note that your CSVFormat (or equivalent, such as a reference to RFC 4180) must be communicated along with the CSV file.
@petelam Yes, you could put all that into one method. But why would you want to? Generally, you should keep a method short, focused on a single task with a narrow focus. Sub-tasks can be moved out to other methods, so one method calls other methods. This makes your code easier to read, easier to debug, and easier to maintain. Look at the main method, see how it reads like an outline for a paper or a table-of-contents of a book, so you can get a sense of what's going on without wading through pages of code.
0

Make sure you call csv.flush() before closing the file. :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.