1

I have a CSV that I generate by building StringBuilder and writing to using PrintWriter. Then I read that CSV again and append something to it, but it messes up the cell which has double quotes in it, used to denote inches. It prints double-quotes twice as 15"

One of the values being added to StringBuilder is this:

Code 1.1

String title = "Poly Nuclear 15\" Laptop Series Notebook Intel Windows10+ 7.6V Battery 8GB Memory"
Text t1 = new Text();
t1.setContent(title);

if (title.contains("\"")) {
      t1.setContent("Poly Nuclear 15\\\" Laptop Series Notebook Intel Windows10+ 7.6V Battery 8GB Memory");
}

My first output (after writing comma separated String created using StringBuilder) using PrintWriter is this:

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filename, true), StandardCharsets.UTF_8);
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
printWriter.println(stringBuilder.toString());
key,date,ms_id,title,alertId
190-2,2022-02-20 12:35:09,107193,Poly Nuclear 15"  Laptop Series Notebook Intel Windows10+ 7.6V Battery 8GB Memory,

Code 1.2

Now I am adding the last column's value alertId at the of each row. I am reading and appending to each row, then writing back to CSV as follows:

// Here below method is called as writeBack("1222") with fixed value.
public void writeBack(String value) {
      String filePath = "/dir1/dir2/test.csv";
      String key = "alertId"; // column name for which value needs to be added.
      InputStreamReader inputStreamReader = new InputStreamReader(new 
      FileInputStream(filePath), StandardCharsets.UTF_8);
      CSVReader reader = new CSVReader(inputStreamReader);

      String[] header = reader.readNext();
      int columnNum = Arrays.asList(header).indexOf(key);

      List<String[]> feedData = reader.readAll();
      try {
        for (String[] row : feedData) {
          row[columnNum] = value;
        }
        reader.close();

        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filePath), StandardCharsets.UTF_8);
        CSVWriter writer = new CSVWriter(outputStreamWriter);
        writer.writeNext(header);
        writer.writeAll(feedData);
        writer.flush();
        writer.close();
      } catch (Exception e) {
        writeLog("ERROR", e);

      }
}

My final output is this where everything is correct except the String value has double quotes as 15""

"key","date","ms_id","title","alertId"
"190-2","2022-02-20 12:35:09","107193","Poly Nuclear 15""  Laptop Series Notebook Intel Windows10+ 7.6V Battery 8GB Memory","1222"

What can I do to avoid double quotes in the final output within the cell that denotes inches?

Expected output

"key","date","ms_id","title","alertId"
"190-2","2022-02-20 12:35:09","107193","Poly Nuclear 15\"  Laptop Series Notebook Intel Windows10+ 7.6V Battery 8GB Memory","1222"
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Atihska
  • 4,803
  • 10
  • 56
  • 98
  • Does this answer your question? [Unwanted double quotes in generated csv file](https://stackoverflow.com/questions/13969254/unwanted-double-quotes-in-generated-csv-file) – SaleemKhair Apr 16 '22 at 07:51
  • @SaleemKhair No, I want quotes in fact and want to escape the ones within the cell and print `\"` instead of erroring out. I am unable to escape the ones within the cell as of now. – Atihska Apr 16 '22 at 08:01
  • I just tested it, using `CSVWriter.NO_QUOTE_CHARACTER` and `CSVWriter.NO_ESCAPE_CHARACTER` create your writer like this `final CSVWriter writer = new CSVWriter(new java.io.FileWriter("/path/to/csv", false), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END)`, then executing `writer.writeNext(new String[] {"bar", "foo measure 3\" in inches"});` – SaleemKhair Apr 16 '22 at 08:56
  • *My final output is this where everything is correct except the String value has double quotes as...* Interestingly that seems to be quite acceptable to my spreadsheet application (LibreOffice Calc). I haven't tried it in Excel – g00se Apr 16 '22 at 09:53
  • 1
    Escaping double quotes by adding an extra double quote conforms to [RFC-4180](https://datatracker.ietf.org/doc/html/rfc4180#page-2): _"If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote."_, so it is the standard way of escaping a double quote. In any case, if you want a different escape, and if this is opecsv, you need to use the constructor `CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd)` to configure the writer to use a different escape character. – Mark Rotteveel Apr 16 '22 at 14:07

1 Answers1

0

Thank you @Mark Rotteveel for the pointer tip. This helped me to look for a different separator and also escape more characters.

Realized that CSVReader and CSVWriter has different escape characters too.

I finally solved using the follwing:

import org.apache.commons.lang.StringEscapeUtils;
...

StringEscapeUtils.escapeCsv("Poly Nuclear 15\" Laptop Series, Notebook \\ Intel Windows10+ 7.6V Battery 8GB Memory")

And using this while writing:

import com.opencsv.ICSVWriter;
...
char escapeChar = '\\';
CSVWriter writer = new CSVWriter(outputStreamWriter, ICSVWriter.DEFAULT_SEPARATOR, ICSVWriter.DEFAULT_QUOTE_CHARACTER, escapeChar, ICSVWriter.DEFAULT_LINE_END);
Atihska
  • 4,803
  • 10
  • 56
  • 98