web-dev-qa-db-fra.com

Problème d'encodage de l'export Javascript vers csv

J'ai besoin d'exporter un tableau javascript vers un fichier Excel et de le télécharger, je le fais dans ce code. data est un tableau d'objets javascript.

var csvContent = "data:text/csv;charset=utf-8,";
data.forEach(function(dataMember, index)
{
    dataString = dataMember.join(",");
    csvContent += index < data.length ? dataString+ "\n" : dataString;
}); 

var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "upload_data" + (new Date()).getTime() + ".csv");
link.click();

Tout cela fonctionne bien jusqu'à ce que j'ai des propriétés de chaîne qui ont des caractères non anglais, comme l'espagnol, l'arabe ou l'hébreu. Comment puis-je exporter avec toutes ces valeurs non-ASCII?

51
Boltosaurus

Vous devez ajouter la nomenclature UTF-8 au début du texte, comme suit:

var csvContent = "data:text/csv;charset=utf-8,%EF%BB%BF";

Cela a fonctionné pour moi avec Excel 2013.

Demo Fiddle

81
Gergő Nagy

Vous pouvez ajouter la nomenclature en premier, utilisez ce code et essayez

var BOM = "\uFEFF"; 
var csvContent = BOM + csvContent;

puis créez les en-têtes de fichier avec les données: "text/csv; charset = utf-8"

64
Marcelo Lujan

Excel détecte très mal l’encodage, en particulier Excel sur OSX.

La meilleure solution serait de coder votre CSV dans le codage Excel par défaut: windows-1252 (également appelé ANSI, qui est fondamentalement un sous-ensemble de la norme ISO-8859-1).

Je mets un exemple complet de la procédure à suivre à: https://github.com/b4stien/js-csv-encoding .

Les 2 parties principales sont stringencoding (pour encoder le contenu de votre CSV dans windows-1252) et FileSaver.js (pour télécharger le blob généré).

Ça ressemble à:

var csvContent = 'éà; ça; 12\nà@€; çï; 13',
    textEncoder = new TextEncoder('windows-1252');


var csvContentEncoded = textEncoder.encode([csvContent]);
var blob = new Blob([csvContentEncoded], {type: 'text/csv;charset=windows-1252;'});
saveAs(blob, 'some-data.csv');
15
b4stien

Option 1

utilisation iconv-lite bibliothèque et encodez votre sortie en ascii avant de la renvoyer à l'utilisateur. Exemple:

var iconv = require('iconv-lite');
buf = iconv.encode(str, 'win1255'); // return buffer with windows-1255 encoding

Option 2

Écrivez sur l'en-tête du fichier l'en-tête de nomenclature du codage UTF-8. Exemple:

res.header('Content-type', 'text/csv; charset=utf-8');
res.header('Content-disposition', 'attachment; filename=Excel.csv'); 
res.write(Buffer.from('EFBBBF', 'hex')); // BOM header

// rest of your code

Option

Utilisez le format url base64 comme data:text/csv;base64,77u/Zm9vLGJhcg0KYWFhLGJiYg==. Cette méthode fonctionnera également côté client (IE10 +, FF, Chrome, Opera, Safari).

Par exemple:

window.location = "data:text/csv;base64,77u/" + btoa("foo,bar\r\naaa,bbb");
4
Moshe Simantov

en quelque sorte trouvé Tab-Separated-CSV avec encodage utf-16le avec nomenclature fonctionne sur WIN/MAC Excel

suivi la réponse de b4stien mais faire une petite différence pour archiver:

var csvContent = 'éà; ça; 12\nà@€; çï; 13',
    textEncoder = new TextEncoder('utf-16le');
var csvContentEncoded = textEncoder.encode([csvContent]);
var bom = new Uint8Array([0xFF, 0xFE]);
var out = new Uint8Array( bom.byteLength + csvContentEncoded.byteLength );
out.set( bom , 0 );
out.set( csvContentEncoded, bom.byteLength );
var blob = new Blob([out]);
saveAs(blob, 'some-data.csv');

avec les tests Linux/usr/bin/file:

Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators
2
gjchen

B4stien, merci à vous pour votre réponse! Après avoir testé plusieurs solutions basées sur charset "utf8", l'encodage de windows-1252 est la seule solution qui m'a permis de garder mon accent dans Excel 365!

Manetsus, la réponse de b4stien et son lien ont été très utiles pour mon cas: je dois exporter des données françaises et allemandes dans un fichier csv: aucune solution basée sur "utf8" n'a fonctionné ... Seule sa solution utilisant un "ANSI" (fenêtre -1252) encodeur ...

Je donne son exemple de code, et vous pouvez télécharger les fichiers encoding-indexes.js, encoding.js et FileSaver.js dépendant du lien ...

    <!doctype html>
    <html>

    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="encoding-indexes.js"></script>
        <script type="text/javascript" src="encoding.js"></script>
        <script type="text/javascript" src="FileSaver.js"></script>
    </head>

    <body>
        <a href="#" id="download-csv">Click me to download a valid CSV !</a>

        <script type="text/javascript">
            var csvContent = 'éà; ça; 12\nà@€; çï; 13',
                textEncoder = new CustomTextEncoder('windows-1252', {NONSTANDARD_allowLegacyEncoding: true}),
                fileName = 'some-data.csv';

            var a = document.getElementById('download-csv');
            a.addEventListener('click', function(e) {
                var csvContentEncoded = textEncoder.encode([csvContent]);
                var blob = new Blob([csvContentEncoded], {type: 'text/csv;charset=windows-1252;'});
                saveAs(blob, fileName);
                e.preventDefault();
            });
        </script>
    </body>

    </html>

Néanmoins, comme Excel est relativement ouvert dans le support des langues et des formats, je n’exclue pas que UTF8 ne soit pas pris en charge dans mon environnement de développement en raison de la manière dont il est installé ...

Remarque: je le teste avec Firefox, Chrome et IE 11 sur Windows 7, avec Excel 365 ...

0
Didier68