web-dev-qa-db-fra.com

sep = ";" instruction rompt la nomenclature utf8 dans un fichier CSV généré par XSL

Je développe actuellement l'exportation CSV avec XSLT. Et le fichier CSV sera utilisé à 99% avec Excel dans mon cas, je dois donc tenir compte du comportement d'Excel. 

Mon premier problème était les caractères spéciaux allemands dans csv. Même si le codage CSV est UTF8, Excel ne peut pas ouvrir correctement le fichier CSV avec UTF8. Les caractères spéciaux deviennent des symboles étranges. J'ai trouvé une solution à ce problème. Je viens d'ajouter 3 octets supplémentaires (EF BB BF - a.k.a BOM Header) début d'octets de contenu. Parce que la nomenclature UTF8 est une façon de dire que "hé mec, c’est UTF8, ouvrez-le correctement" dans Excel. Problème résolu!

Et mon deuxième problème concernait le séparateur. Le séparateur par défaut peut être une virgule ou un point-virgule selon la région. Je pense que c'est un point-virgule en Allemagne et une virgule au Royaume-Uni. Donc, afin d'éviter ce problème, j'ai dû ajouter la ligne ci-dessous:

<xsl:text>sep=;</xsl:text>

ou

<xsl:text>sep=,</xsl:text>

(Ce séparateur n'a pas été implémenté comme codé en dur)

Mais mon problème auquel je ne trouve aucune solution est que si vous ajoutez "sep =;" ou "sep =", début du fichier lorsque le fichier CSV est généré avec UT8-BOM, la nomenclature ne permet plus d'afficher correctement les caractères spéciaux! Et je suis sûr que les octets de nomenclature sont toujours au début du tableau d'octets. Cette capture d'écran provient de MS Excel sous Mac OS X:

enter image description here

Les 3 premiers symboles appartiennent à l'en-tête de la nomenclature. 

Avez-vous déjà eu ce problème ou avez-vous des suggestions? Je vous remercie.

Modifier:

Je partage les screenscreens. 

une. Avec nomenclature et<xsl:text>sep=;</xsl:text>

enter image description here

b. Juste avec BOM

enter image description here

Le code Java:

// Write the bytes
ServletOutputStream out = resp.getOutputStream();
if(contentType.toString().equals("CSV")) {
  // The additional bytes in below is prefix indicates that the content is in UTF-8.
  out.write(239);
  out.write(187);
  out.write(191);
} 
out.write(bytes); // Content bytes, in this case XSL

Le code XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
    <xsl:text>sep=;</xsl:text>
    <table>
        ...
        </table>
</xsl:template>
25
Adem İlhan

Ceci est le résultat de mes tests avec Excel 2013.

Si vous êtes bloqué avec UTF-8, il existe une solution de contournement consistant en BOM + data + sep =;

Entrée (écrite avec le codage UTF8)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff sep=;

Sortie |Some|Header|Columns| |Wîth|Fàncÿ |Stûff | |sep=| | |

Le problème avec la solution est que bien qu'Excel interprète correctement sep=;, il affiche sep= (oui, il avalera le ;) dans la première colonne de la dernière ligne.

Toutefois, si vous pouvez écrire le fichier au format UTF16-LE, il existe une solution concrète. Utilisez le délimiteur \t sans spécifier sep et Excel jouera au ballon.

Entrée (écrite avec le codage UTF16-LE)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff

Sortie |Some|Header|Columns| |Wîth|Fàncÿ |Stûff |

8
Pier-Luc Gendreau

Vous avez raison, Excel 2007 ne permet pas de charger correctement le codage et le séparateur dans des environnements locaux différents lorsque quelqu'un clique deux fois sur un fichier CSV.

Il semble que lorsque vous spécifiez sep = après la nomenclature, il oublie que la nomenclature lui a indiqué qu'il s'agissait du format UTF-8.

Vous devez spécifier la nomenclature, car dans certaines langues, Excel ne détecte pas le séparateur. Par exemple, en danois, le séparateur par défaut est. Si vous produisez du texte séparé par des virgules ou des tabulations, il ne détectera pas le séparateur et, dans les autres paramètres régionaux, si vous séparez des points-virgules, il ne se charge pas. Vous pouvez le tester en modifiant le format de localisation dans les paramètres de Windows. Excel le sélectionne ensuite.

A partir de cette question: Est-il possible de forcer Excel à reconnaître automatiquement les fichiers UTF-8 CSV?

et la solution semble être que le seul moyen est d’utiliser le codage de fichier UTF16 avec BOM.

Notez également que selon http://wiki.scn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator?original_fqdn=wiki.sdn.sap.com il semble que si vous utilisez utf16-le avec des séparateurs de tabulation, alors cela fonctionne.

Je me suis demandé si Excel lit sep =; et réappelle ensuite la méthode pour obtenir le texte CSV et perd la nomenclature. J'ai essayé de donner un texte incorrect et je ne trouve aucune solution qui indique à Excel de prendre à la fois le sep et l'encodage.

8
Luke Page

Je ne peux pas encore écrire de commentaires, mais j'aimerais aborder la solution de @ Pier-Luc Gendreau. Bien qu'il soit possible de l'ouvrir dans Excel européen (qui utilise par défaut ; comme délimiteur) et de prendre en charge pleinement utf-16LE, il n'est apparemment pas possible d'utiliser cette technique lorsque vous spécifiez sep=,

Le problème avec la solution est que, même si Excel interprète sep =; correctement, il affiche sep = (oui, il avale le;) dans la première colonne de la dernière ligne.

Pour moi, cela ne fonctionnait pas si je spécifiais un délimiteur qui n'était pas celui par défaut (;dans mon cas), donc je suppose qu'Excel n'a pas interprété correctement la dernière ligne et a avalé le dernier délimiteur car il s'agit du comportement par défaut. 

Corrigez-moi si j'ai tort, s'il-vous plait

0
MichiOnStack