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

59

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

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

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

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

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

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

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

  • 1
    Я уверен, что Oracle (и остальные основные СУБД) имеют функцию экспорта, которая выполняет эту функцию. За исключением этого, вероятно, есть версия с открытым исходным кодом, которая будет взаимодействовать практически с чем угодно через JDBC, учитывая, насколько распространен этот тип функциональности.
  • 0
    Спасибо X-Zero, но здесь работа фактически зависит от контроллера. Но все равно очень полезная идея :)
Показать ещё 1 комментарий
Теги:
csv
excel

7 ответов

90
Лучший ответ

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


❐ 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();
    

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

  • 0
    Спасибо за совет, Пол. Это хорошая идея и достаточно гибкая с rgx, но можем ли мы достичь этого без дополнительных библиотек?
  • 0
    И еще раз, Пол, это действительно поддерживающая идея и полезная информация, если в следующем проекте я могу иметь привилегию добавить больше зависимостей в Maven. : D
Показать ещё 11 комментариев
33

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"""
  • 0
    Тони, это хорошая идея. Я должен думать так, тогда это должна быть легкая работа.
  • 3
    Как избежать """" ?
Показать ещё 2 комментария
11

Благодаря Тони и Полю для быстрой обратной связи, это очень полезно. Я действительно выясняю решение через 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+"\"")

3

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

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

  • 0
    Спасибо, Ли Аунг. Я не получил ваш пост до того, как опубликовал свой собственный ответ. Python получает больше библиотечных методов для создания CVS.
  • 0
    Оригинальный вопрос не упоминает Python.
Показать ещё 1 комментарий
2
"cell one","cell "" two","cell "" ,three"

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

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

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

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

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

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

  • 0
    Обратите внимание, что на вопрос уже дан ответ, и ответ принят. Ваше предлагаемое решение не стоит за запятыми.
-1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню