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?
Il y a plusieurs bibliothèques. Voici deux exemples:
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 .
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 .
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"""
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+"\""
)
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 ""
.
"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 "
String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";
cela conservera la virgule dans le fichier CSV