Search code examples
javacsvexport-to-csvquotesupercsv

SuperCSV quote every exported cell


I'm using superCSV for exporting bean data to CSV. I'd like every cell double quoted, not just the ones with special characters.

Now, using CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE, even the cells with special characters won't get quoted. (With EXCEL_PREFERENCE setting the addresses that contain '.' get quoted.)

My goal is to export addresses, phone numbers, everything in a way that MS Office (Hungarian) can use and i.e. won't convert phone numbers like +36000000000 to 36000000000.


Solution

  • Edit: Update for Super CSV 2.1.0

    Since Super CSV 2.1.0, you can now specify a QuoteMode via the preferences to enable quotes when they're normally not required. To quote every column, you can use the inbuilt AlwaysQuoteMode. If want to enable quotes for particular columns, use the ColumnQuoteMode. Please note that you can't disable quoting this way, you'd have to supply your own CsvEncoder to do that.


    Thanks for bringing that forum post to my attention! Looks like Kasper didn't get around to implementing that feature. I'll see what I can do for the upcoming release :)

    Instead of hacking the Super CSV source to add this 'quote everything' functionality, you could extend the Super CSV implementation in your own project . As you've mentioned, Super CSV only quotes the whole field if it contains special characters (quote, comma, etc) - it also does it if the field contains leading/trailing spaces.

    With this in mind there's no reason you can't write your own Writer which overrides the escapeString() method (you just have to make sure it's not already quoted).

    package org.supercsv.io;
    
    import java.io.Writer;
    
    import org.supercsv.prefs.CsvPreference;
    
    public class QuoteAllCsvBeanWriter extends CsvBeanWriter {
    
        public QuoteAllCsvBeanWriter(Writer writer, CsvPreference preference) {
            super(writer, preference);
        }
    
        @Override
        protected String escapeString(String csvElement) {
    
            // perform normal escaping
            final String escaped = super.escapeString(csvElement);
    
            // add surrounding quotes if required
            final String quote = String.valueOf((char) preference.getQuoteChar());
            if (escaped.startsWith(quote) && escaped.endsWith(quote)){
                return escaped;
            } else {
                return quote + escaped + quote;
            }
        }
    
    }