Как избежать запятой и двойной кавычки в то же время для CSV файла?

Я пишу приложение Java для экспорта данных из Oracle в файл csv

К сожалению, содержание данных может быть довольно сложным. Еще запятая - это разделитель, но некоторые данные в строке могут быть такими:

ID FN LN ВОЗРАСТ КОММЕНТАРИЙ

123, Джон, Смит, 39, я сказал: "Эй, я 5'10".

так что это одна из строк в столбце comment:

Я сказал: "Эй, я 5'10".

Не шутите, мне нужно показать выше комментарий без компромиссов в excel или open office из CSV файла, сгенерированного Java, и, конечно же, не может испортить другую обычную ситуацию экранирования (т.е. регулярные двойные кавычки и регулярную запятую в кортеже), Я знаю, что регулярное выражение является мощным, но как мы можем достичь цели с такой сложной ситуацией?

Ответ 1

Существует несколько библиотек. Вот два примера:


❐ Apache Commons Lang

Apache Commons Lang включает специальный класс для escape-или unescape-строк (CSV, EcmaScript, HTML, Java, Json, XML): org.apache.commons.lang3.StringEscapeUtils.

  • Escape to CSV

    String escaped = StringEscapeUtils
        .escapeCsv("I said \"Hey, I am 5'10\".\""); // I said "Hey, I am 5'10"."
    
    System.out.println(escaped); // "I said ""Hey, I am 5'10""."""
    
  • Unescape из CSV

    String unescaped = StringEscapeUtils
        .unescapeCsv("\"I said \"\"Hey, I am 5'10\"\".\"\"\""); // "I said ""Hey, I am 5'10""."""
    
    System.out.println(unescaped); // I said "Hey, I am 5'10"."
    

* Вы можете скачать его из здесь.


❐ OpenCSV

Если вы используете OpenCSV, вам не нужно беспокоиться о побеге или unescape, только для записи или чтения контента.

  • Написание файла:

    FileOutputStream fos = new FileOutputStream("awesomefile.csv"); 
    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
    CSVWriter writer = new CSVWriter(osw);
    ...
    String[] row = {
        "123", 
        "John", 
        "Smith", 
        "39", 
        "I said \"Hey, I am 5'10\".\""
    };
    writer.writeNext(row);
    ...
    writer.close();
    osw.close();
    os.close();
    
  • Чтение файла:

    FileInputStream fis = new FileInputStream("awesomefile.csv"); 
    InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
    CSVReader reader = new CSVReader(isr);
    
    for (String[] row; (row = reader.readNext()) != null;) {
        System.out.println(Arrays.toString(row));
    }
    
    reader.close();
    isr.close();
    fis.close();
    

* Вы можете скачать его из здесь.

Ответ 2

Excel должен иметь возможность обрабатывать ту же ситуацию.

Поместите эти вещи в Excel, сохраните их как CSV и просмотрите файл с помощью текстового редактора. Затем вы будете знать правила, которые Excel применяет к этим ситуациям.

Сделать Java выдавать тот же результат.

Форматы, используемые Excel, публикуются, кстати...

**** Редактировать 1: **** Вот что делает Excel **** Редактировать 2: **** Обратите внимание, что php fputcsv выполняет то же самое, что и excel, если вы используете "как приложение".

[email protected]
Richard
"This is what I think"

преобразуется в это:

Email,Fname,Quoted  
[email protected],Richard,"""This is what I think"""

Ответ 3

Спасибо и Тони, и Полу за быструю обратную связь, это очень полезно. Я на самом деле найти решение через POJO. Вот оно:

if (cell_value.indexOf("\"") != -1 || cell_value.indexOf(",") != -1) {
    cell_value = cell_value.replaceAll("\"", "\"\"");
    row.append("\"");
    row.append(cell_value);
    row.append("\"");
} else {
    row.append(cell_value);
}
Короче говоря,

если в строке рядом с ячейкой есть специальный символ, такой как запятая или двойная кавычка, то сначала нужно убрать двойную кавычку ("\""), добавив дополнительную двойную кавычку (например, "\"\""), а затем поставить целую вещь в двойные кавычки (как "\""+theWholeThing+"\"")

Ответ 4

Вы также можете посмотреть, как Python записывает файлы с поддержкой Excel csv.

Я считаю, что значение по умолчанию для Excel заключается в удвоении для буквенных символов кавычек, т.е. буквенные кавычки " записываются как "".

Ответ 5

"cell one","cell "" two","cell "" ,three"

Сохраните это в csv файле и посмотрите результаты, поэтому двойная кавычка используется для выхода из себя

Важное примечание

"cell one","cell "" two", "cell "" ,three"

даст вам другой результат, потому что после запятой есть пробел, и это будет рассматриваться как "

Ответ 6

Если вы используете CSVWriter. Убедитесь, что у вас нет опции

.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)

Когда я удалил ее, запятая показывалась, как и ожидалось, и не воспринимала ее как новый столбец

Ответ 7

String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";

это сохранит запятую в файле CSV

Ответ 8

Я просто использую функцию fputcsv($fp, $res,',',' '); и получить правильные csv.