web-dev-qa-db-fra.com

Exporter des données javascript vers un fichier CSV sans interaction du serveur

Si nous étions sur un serveur nodeJS, nous pourrions écrire un en-tête, définir un type mime et l'envoyer:

res.header("Content-Disposition", "attachment;filename="+name+".csv"); 
res.type("text/csv");
res.send(200, csvString);

et à cause des en-têtes, le navigateur créera un téléchargement pour le fichier csv nommé.

Lorsque des données utiles sont générées dans un navigateur, une solution pour les obtenir dans un fichier CSV consiste à utiliser ajax, de les télécharger sur le serveur (éventuellement de les enregistrer ici) et de les renvoyer au serveur avec ces en-têtes pour qu'ils deviennent Csv télécharger de nouveau sur le navigateur.

Cependant, j'aimerais une solution de navigateur à 100% qui n'implique pas de ping-pong avec le serveur.

Il m'est donc apparu que l'on pouvait ouvrir une nouvelle fenêtre et essayer de définir l'en-tête avec une balise META équivalente. 

Mais cela ne fonctionne pas pour moi dans Chrome récent. 

Je reçois une nouvelle fenêtre, qui contient le csvString, mais n’agit pas comme un téléchargement.

Je suppose que je m'attendais à obtenir un téléchargement dans un onglet inférieur ou une nouvelle fenêtre vierge avec un téléchargement dans un onglet inférieur. 

Je me demande si les balises META sont correctes ou si d'autres balises sont également nécessaires.

Existe-t-il un moyen de faire fonctionner ce travail sans l’aiguiller vers le serveur?

JsFiddle pour créer un fichier CSV dans le navigateur (ne fonctionne pas - fenêtre des sorties mais pas de téléchargement)

var A = [['n','sqrt(n)']];  // initialize array of rows with header row as 1st item
for(var j=1;j<10;++j){ A.Push([j, Math.sqrt(j)]) }
var csvRows = [];
for(var i=0,l=A.length; i<l; ++i){
    csvRows.Push(A[i].join(','));   // unquoted CSV row
}
var csvString = csvRows.join("\n");
console.log(csvString);
var csvWin = window.open("","","");
csvWin.document.write('<meta name="content-type" content="text/csv">');
csvWin.document.write('<meta name="content-disposition" content="attachment;  filename=data.csv">  ');
csvWin.document.write(csvString);
74
Paul

Il y a toujours l'attribut HTML5 download :

Cet attribut, s'il est présent, indique que l'auteur a l'intention d'utiliser le lien hypertexte à utiliser pour télécharger une ressource afin que l'utilisateur clique sur le lien, il leur sera demandé de l’enregistrer en tant que fichier local.

Si l'attribut a une valeur, celle-ci sera utilisée en tant que .__ pré-rempli. nom de fichier dans l'invite de sauvegarde qui s'ouvre lorsque l'utilisateur clique sur le fichier lien. 

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.Push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.Push(A[i].join(','));
}

var csvString = csvRows.join("%0A");
var a         = document.createElement('a');
a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
a.target      = '_blank';
a.download    = 'myFile.csv';

document.body.appendChild(a);
a.click();

FIDDLE

Testé sous Chrome et Firefox, fonctionne parfaitement dans les dernières versions (à partir de juillet 2013).
Fonctionne également dans Opera, mais ne définit pas le nom de fichier (à compter de juillet 2013).
Ne semble pas fonctionner dans IE9 (grosse surprise) (en juillet 2013).

Vous pouvez trouver un aperçu de la manière dont les navigateurs prennent en charge l'attribut de téléchargement Here
Pour les navigateurs non compatibles, il est nécessaire de définir les en-têtes appropriés sur le côté serveur.


Apparemment, il y a un hack pour IE10 et IE11 , qui ne prend pas en charge l'attribut download(Edge cependant)

var A = [['n','sqrt(n)']];

for(var j=1; j<10; ++j){ 
    A.Push([j, Math.sqrt(j)]);
}

var csvRows = [];

for(var i=0, l=A.length; i<l; ++i){
    csvRows.Push(A[i].join(','));
}

var csvString = csvRows.join("%0A");

if (window.navigator.msSaveOrOpenBlob) {
    var blob = new Blob([csvString]);
    window.navigator.msSaveOrOpenBlob(blob, 'myFile.csv');
} else {
    var a         = document.createElement('a');
    a.href        = 'data:attachment/csv,' +  encodeURIComponent(csvString);
    a.target      = '_blank';
    a.download    = 'myFile.csv';
    document.body.appendChild(a);
    a.click();
}
155
adeneo

@adeneo answer fonctionne pour Firefox et chrome ... Pour IE, les éléments ci-dessous peuvent être utilisés.

if (window.navigator.msSaveOrOpenBlob) {
  var blob = new Blob([decodeURIComponent(encodeURI(result.data))], {
    type: "text/csv;charset=utf-8;"
  });
  navigator.msSaveBlob(blob, 'FileName.csv');
}

25
Manu Sharma

Voir la réponse de adeneo, mais n'oubliez pas encodeURIComponent!

a.href     = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvString);

En outre, je devais faire "\ r\n" pas seulement "\ n" pour le délimiteur de lignes.

var csvString = csvRows.join("\r\n");

Violon révisé: http://jsfiddle.net/7Q3c6/

15
user2608223

Une fois que j'ai emballé le code JS faisant cela dans une petite bibliothèque:

https://github.com/AlexLibs/client-side-csv-generator

Le code, la documentation et les démonstrations/terrains de jeu sont fournis sur Github.

Prendre plaisir :)

Les demandes de tirage sont les bienvenues.

7
Alexander

Voir la réponse d'adeneo, mais pour que cela fonctionne dans Excel dans tous les pays, vous devez ajouter "SEP =," à la première ligne du fichier. Cela définira le séparateur standard dans Excel et ne s'affichera pas dans le document réel

var csvString = "SEP=, \n" + csvRows.join("\r\n");
1
Thyselius

Nous pouvons facilement créer et exporter/télécharger le fichier Excel avec n’importe quel séparateur (j’utilise le séparateur de virgule dans cette réponse) en utilisant javascript. Je n'utilise aucun logiciel externe pour créer le fichier Excel.

    var Head = [[
        'Heading 1',
        'Heading 2', 
        'Heading 3', 
        'Heading 4'
    ]];

    var row = [
       {key1:1,key2:2, key3:3, key4:4},
       {key1:2,key2:5, key3:6, key4:7},
       {key1:3,key2:2, key3:3, key4:4},
       {key1:4,key2:2, key3:3, key4:4},
       {key1:5,key2:2, key3:3, key4:4}
    ];

for (var item = 0; item < row.length; ++item) {
       Head.Push([
          row[item].key1,
          row[item].key2,
          row[item].key3,
          row[item].key4
       ]);
}

var csvRows = [];
for (var cell = 0; cell < Head.length; ++cell) {
       csvRows.Push(Head[cell].join(','));
}
            
var csvString = csvRows.join("\n");
let csvFile = new Blob([csvString], { type: "text/csv" });
let downloadLink = document.createElement("a");
downloadLink.download = 'MYCSVFILE.csv';
downloadLink.href = window.URL.createObjectURL(csvFile);
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();

0
Pulkit Aggarwal