web-dev-qa-db-fra.com

Comment échapper à la virgule et aux guillemets en même temps pour un fichier CSV?

J'écris une application Java pour exporter des données d'Oracle vers un fichier csv

Malheureusement, le contenu des données peut être assez délicat. Encore une virgule est le séparateur, mais certaines données sur une ligne pourraient ressembler à ceci:

IDFNLNAGECOMMENTAIRE

123, John, Smith, 39 ans, j'ai dit "Hé, je suis 5'10". "

c'est donc l'une des chaînes de la colonne comment:

J'ai dit "Hé, je suis 5'10". "

Sans blague, je dois montrer le commentaire ci-dessus sans compromis dans Excel ou Open Office à partir d'un fichier CSV généré par Java, et bien sûr, je ne peux pas gâcher une autre situation d'échappement normale (par exemple, des guillemets doubles et une virgule dans un Tuple). Je sais que l'expression régulière est puissante, mais comment pouvons-nous atteindre l'objectif avec une situation aussi compliquée?

60
Dreamer

Il y a plusieurs bibliothèques. Voici deux exemples:


❐ Apache Commons Lang

Apache Commons Lang inclut une classe spéciale pour échapper ou annuler les chaînes (CSV, EcmaScript, HTML, Java, Json, XML): org.Apache.commons.lang3.StringEscapeUtils .

  • Escape au format 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 de 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"."
    _

* Vous pouvez le télécharger à partir de ici .


❐ OpenCSV

Si vous utilisez OpenCSV , vous n'aurez plus à vous soucier de l'évasion ou de l'unescape, uniquement pour écrire ou lire le contenu.

  • Fichier d'écriture:

    _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();
    _
  • Lecture du fichier:

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

* Vous pouvez le télécharger à partir de ici .

102
Paul Vargas

Excel doit être capable de gérer exactement la même situation.

Mettez ces éléments dans Excel, enregistrez-les au format CSV et examinez le fichier avec un éditeur de texte. Vous saurez alors quelles règles Excel applique à ces situations.

Faire en sorte que Java produise le même résultat.

Les formats utilisés par Excel sont publiés, à propos ...

**** Edit 1: **** Voici ce que fait Excel
**** Edit 2: **** Notez que fputcsv de php fait exactement la même chose qu'Excel si vous utilisez "comme enceinte. 

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

se transforme en ceci:

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

Merci à Tony et Paul pour leurs commentaires rapides, c’est très utile. En fait, je trouve une solution via POJO. C'est ici:

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);
}

en bref, s'il y a un caractère spécial comme une virgule ou une double citation dans la chaîne située dans la cellule, échappez d'abord à la citation ("\"") en ajoutant une citation double (comme "\"\""), puis mettez le tout dans une citation double "\""+theWholeThing+"\"")

13
Dreamer

Vous pouvez également regarder comment Python écrit des fichiers csv compatibles avec Excel.

Je crois que la valeur par défaut pour Excel est de doubler les caractères de citation littérale - autrement dit, les guillemets littéraux " sont écrits sous la forme "".

3
Li-aung Yip
"cell one","cell "" two","cell "" ,three"

Enregistrez ceci dans un fichier csv et visualisez les résultats. Un guillemet double est donc utilisé pour s'échapper.

Note importante

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

vous donnera un résultat différent car il y a un espace après la virgule, et cela sera traité comme "

2
A.Zaben
String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";

cela conservera la virgule dans le fichier CSV

0
Ashiq M