27 votes

Obtenir des données CSV à partir du presse-papiers (collées depuis Excel) qui contiennent des caractères accentués

SCÉNARIO

  • Mes utilisateurs copieront des cellules d'Excel (en les plaçant dans le presse-papiers).
  • Et mon application récupérera ces cellules dans le presse-papiers.

LE PROBLÈME

  • Mon code récupère le format CSV à partir du presse-papiers.
  • Cependant, si le contenu original d'Excel contient des caractères comme ä (a avec tréma), la chaîne CSV récupérée n'a pas les caractères corrects (ä finit par apparaître comme un "carré" pour moi).
  • En comparaison, si mon code récupère le format de texte Unicode à partir du presse-papiers, tout fonctionne bien : le ä est préservé dans la chaîne récupérée dans le presse-papiers.

CODE SOURCE - ORIGINAL - AVEC LE PROBLÈME

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    // read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = new System.Text.UTF8Encoding();
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv = reader.ReadToEnd();

    // read the unicode string
    string data_string = System.Windows.Forms.Clipboard.GetText();

}

LES RÉSULTATS DE L'EXÉCUTION DE L'ÉCHANTILLON DE CODE

  • Repro étapes : Entrez du texte dans Excel (j'ai utilisé le mot "doppelgänger" et quelques chiffres) et appuyez simplement sur Ctrl-C pour le copier dans le presse-papiers, puis exécutez le code ci-dessus.
  • data_csv est réglé sur "doppelgnger,1". \r\n2 ,3 \r\n\0 "
  • data_string a pour valeur "doppelgänger". \t1\r\n2\t3\r\n "

QUESTION

  • Que puis-je faire pour obtenir les bons caractères ?

COMMENTAIRES

  • Oui, je sais que je pourrais contourner ce problème en utilisant le texte Unicode. Mais je veux en fait comprendre ce qui se passe avec le CSV.
  • L'utilisation ou non de l'encodage UTF-8 lors de la récupération du flux ne fait aucune différence dans les résultats.

LA RÉPONSE

Après avoir examiné les commentaires et prêté une attention particulière à ce qu'Excel mettait dans le presse-papiers pour le CSV, il semblait raisonnable qu'Excel place le contenu en utilisant un encodage "ancien" au lieu d'UTF-8. J'ai donc essayé d'utiliser le codepage Windows 1252 comme encodage et cela a fonctionné. Voir le code ci-dessous

CODE SOURCE - AVEC LA RÉPONSE

[STAThread]
static void Main(string[] args)
{
    var fmt_csv = System.Windows.Forms.DataFormats.CommaSeparatedValue;

    //read the CSV
    var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
    var stream = (System.IO.Stream)dataobject.GetData(fmt_csv);
    var enc = System.Text.Encoding.GetEncoding(1252);
    var reader = new System.IO.StreamReader(stream,enc);
    string data_csv= reader.ReadToEnd();

    //read the Unicode String
    string data_string = System.Windows.Forms.Clipboard.GetText();
}

7voto

Peter Ruderman Points 6151

Excel enregistre la chaîne de caractères dans le presse-papiers en utilisant l'encodage de caractères Unicode. La raison pour laquelle vous obtenez un carré lorsque vous essayez de lire la chaîne en ANSI est qu'il n'y a pas de représentation pour ce caractère dans la page de code ANSI de votre système. Vous devriez simplement utiliser Unicode. Si vous devez faire face à des problèmes de localisation, ANSI vous causera plus de problèmes qu'il n'en vaut la peine.

Edit : Joel Spolsky a écrit une excellente introduction aux codages de caractères, qui vaut vraiment la peine d'être consultée : Le minimum absolu que tout développeur de logiciels doit absolument, positivement connaître sur Unicode et les jeux de caractères (pas d'excuses !)

1voto

Larry K Points 16266

Votre encodage du flux en UTF8 ne fonctionne pas. Les octets pour le tréma sont convertis en caractère unicode "caractère de remplacement".

Au lieu de cela, il suffit de regarder les données du flux sans instructions d'encodage supplémentaires. Les données seront dans un format défini utilisé par Excel. Vous devriez être capable de dire en regardant le(s) octet(s) où se trouve l'unlaut. Vous devriez alors être capable de le convertir en UTF-8.

Le pire des cas est que le formateur CSV rejette tout ce qui n'est pas Ascii. Dans ce cas, vous pourriez être en mesure d'écrire votre propre formateur de données.

Dans certains cas, les gens d'Excel ont compris que CSV signifie uniquement Ascii. Voir http://www.tech-archive.net/Archive/Excel/microsoft.public.excel.misc/2008-07/msg02270.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X