javacsvopencsvcsv-write-streamcsvwriter

Using CSVWriter to write a string array - some with quotes and some without


I see some other questions about CSVWriter writing to files and quotes. But nothing as specific as my issue.

I want to print something like:

abc,def,ghi,"jkl",mno,pqr

When I just write:

CSVWriter writer = new CSVWriter(new FileWriter(getFullPathToTestFile(), true));
String[] newLine = { "abc","def","ghi","jkl","mno","pqr" };
writer.writeNext(newLine);

what gets printed out is:

"abc","def","ghi","jkl","mno","pqr"

So i tried:

CSVWriter writer = new CSVWriter(new FileWriter(getFullPathToTestFile(), true), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
String[] newLine = { "abc","def","ghi","jkl","mno","pqr" };
writer.writeNext(newLine);

which gives me:

abc,def,ghi,jkl,mno,pqr

But I need the quotes on jkl. So I tried something like:

CSVWriter writer = new CSVWriter(new FileWriter(getFullPathToTestFile(), true), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
String[] newLine = { "abc","def","ghi","\""+"jkl"+"\"","mno","pqr" };
writer.writeNext(newLine);

which surprisingly gives me:

abc,def,ghi,""jkl"",mno,pqr

I am out of ideas at this point. Can someone help me understand this and any tips on getting this to work would be much appreciated as well.


Solution

  • First off: I'm assuming you use the com.opencsv.CSVWriter and I'm referring to the documentation at http://opencsv.sourceforge.net/apidocs/com/opencsv/CSVWriter.html

    The syntax in your example array is wrong. abc,def,.. would be variables if you don't quote them, so it probably should read

    String[] newLine = { "abc","def","ghi","\"jkl\"","mno","pqr" };
    

    Also, from the docs I see

    CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd)
    

    but in your code you only use the separator and quotechar parameters, you don't specify escapechar or lineEnd. I assume they will be set to defaults in your version of the library.

    So you tell csvWriter to use "comma" as separator between the values and to explicitly not use quoting, but to escape and use the default line ending. When csvWriter encounters the quote in your "jkl", it tries to escape that by the default mechanism (doubling the quotes).

    You could try adding the quotes to your source and disabling the escaping as well

    CSVWriter writer = new CSVWriter(new FileWriter(getFullPathToTestFile(), true), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);
    

    Depending on your use-case that might be sufficient, but will break e.g. if you have a comma in any of the values.

    As an alternative you could write your own Writer implementation that takes the output of CSVWriter and applies a regular expression to add the quotes on the Nth column.

    CSVWriter writer = new CSVWriter(new RegexpReplaceWriter(new FileWriter(getFullPathToTestFile(), true)), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END);