46 votes

Exportation vers csv en jQuery

Je suis en train de générer dynamiquement un div qui est comme :

<div id='PrintDiv'>
        <table id="mainTable">
            <tr>
                <td>
                    Col1
                </td>
                <td>
                    Col2
                </td>
                <td>
                    Col3
                </td>
            </tr>
            <tr>
                <td>
                    Val1
                </td>
                <td>
                    Val2
                </td>
                <td>
                    Val3
                </td>
            </tr>
            <tr>
                <td>
                    Val11
                </td>
                <td>
                    Val22
                </td>
                <td>
                    Val33
                </td>
            </tr>
            <tr>
                <td>
                    Val111
                </td>
                <td>
                    Val222
                </td>
                <td>
                    Val333
                </td>
            </tr>
        </table>
    </div>

Et il y a aussi beaucoup plus d'éléments sur la page. Comment puis-je obtenir un fichier csv comme celui-ci ?

Col1,Col2,Col3
Val1,Val2,Val3
Val11,Val22,Val33
Val111,Val222,Val333

utiliser jQuery ?

J'ai besoin d'une boîte de dialogue de sauvegarde des fichiers, comme celle-ci :

alt text

Gracias.

1 votes

Vous recherchez une solution côté client et devez éviter un appel au serveur.

1 votes

Excel peut effectivement importer du html formaté comme vous l'avez fait.

0 votes

Plusieurs bibliothèques JavaScript peuvent le faire, notamment Table de données

99voto

italo Points 3353

Vous pouvez le faire du côté client uniquement, dans un navigateur qui accepte URI de données :

data:application/csv;charset=utf-8,content_encoded_as_url

Dans votre exemple, l'URI des données doit être :

data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333

Vous pouvez appeler cette URI par :

  • en utilisant window.open
  • ou le réglage de la window.location
  • ou par le href d'une ancre
  • en ajoutant le download attribut il fonctionnera dans le chrome, doivent encore tester dans l'IE.

Pour tester, il suffit de copier les URI ci-dessus et de les coller dans la barre d'adresse de votre navigateur. Ou testez l'ancre ci-dessous dans une page HTML :

<a download="somedata.csv" href="data:application/csv;charset=utf-8,Col1%2CCol2%2CCol3%0AVal1%2CVal2%2CVal3%0AVal11%2CVal22%2CVal33%0AVal111%2CVal222%2CVal333">Example</a>

Pour créer le contenu, en récupérant les valeurs de la table, vous pouvez utiliser table2CSV et faire :

var data = $table.table2CSV({delivery:'value'});

$('<a></a>')
    .attr('id','downloadFile')
    .attr('href','data:text/csv;charset=utf8,' + encodeURIComponent(data))
    .attr('download','filename.csv')
    .appendTo('body');

$('#downloadFile').ready(function() {
    $('#downloadFile').get(0).click();
});

La plupart des versions d'IE, si ce n'est toutes, ne prennent pas en charge la navigation vers une liaison de données, il faut donc mettre en œuvre un hack, souvent avec un iframe . L'utilisation d'un iFrame combiné avec document.execCommand('SaveAs'..) vous pouvez obtenir un comportement similaire sur la plupart des versions actuelles d'IE.

0 votes

Pour quels navigateurs cela fonctionne-t-il / ne fonctionne-t-il pas ? Il ne semble pas fonctionner dans Chrome.

0 votes

Les URI de données sont pris en charge par Chrome. Jetez-y un coup d'œil : fr.wikipedia.org/wiki/Data_URI#Web_browser_support

0 votes

C'est ce qui est écrit, mais j'ai testé votre réponse et cela n'a pas fonctionné sur IE9 ou Chrome pour moi.

25voto

lepe Points 8959

Il s'agit de ma mise en œuvre (basée sur : https://gist.github.com/3782074 ):

Utilisation : HTML :

<table class="download">...</table>
<a href="" download="name.csv">DOWNLOAD CSV</a>

JS :

$("a[download]").click(function(){
    $("table.download").toCSV(this);    
});

Code :

jQuery.fn.toCSV = function(link) {
  var $link = $(link);
  var data = $(this).first(); //Only one table
  var csvData = [];
  var tmpArr = [];
  var tmpStr = '';
  data.find("tr").each(function() {
      if($(this).find("th").length) {
          $(this).find("th").each(function() {
            tmpStr = $(this).text().replace(/"/g, '""');
            tmpArr.push('"' + tmpStr + '"');
          });
          csvData.push(tmpArr);
      } else {
          tmpArr = [];
             $(this).find("td").each(function() {
                  if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
                      tmpArr.push(parseFloat($(this).text()));
                  } else {
                      tmpStr = $(this).text().replace(/"/g, '""');
                      tmpArr.push('"' + tmpStr + '"');
                  }
             });
          csvData.push(tmpArr.join(','));
      }
  });
  var output = csvData.join('\n');
  var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);
  $link.attr("href", uri);
}

Notas :

  • Il utilise les balises "th" pour les titres. Si elles ne sont pas présentes, elles ne sont pas ajoutées.
  • Ce code détecte les nombres au format : -####.## (Vous devrez modifier le code afin d'accepter d'autres formats, par exemple en utilisant des virgules).

UPDATE :

Mon implémentation précédente fonctionnait bien mais ne définissait pas le nom du fichier csv. The code was modified to use a filename but it requires an < a > element. Il semble que vous ne pouvez pas générer dynamiquement l'élément < a > et déclencher l'événement "click" (peut-être pour des raisons de sécurité ?).

DEMO

http://jsfiddle.net/nLj74t0f/

(Malheureusement, jsfiddle ne parvient pas à générer le fichier, mais génère une erreur : "please use POST request", mais ne laissez pas cette erreur vous empêcher de tester ce code dans votre application).

0 votes

Je pense qu'il y a un if supplémentaire $(this).find("td").each(function() { déclaration dans le else après la vérification de th.

1 votes

Merci, j'ai aussi utilisé celui ci-dessus stackoverflow.com/a/7588465/805366 jsfiddle.net/santeriv/qtQPf

6voto

Paul Points 5437

J'ai récemment mis en ligne une bibliothèque de logiciels libres à cet effet : "html5csv.js" -- GitHub

Il a pour but d'aider à rationaliser la création de petites applications de simulateur en Javascript qui pourraient avoir besoin d'importer ou d'exporter des fichiers csv, de manipuler, d'afficher, de modifier manipuler, afficher, modifier les données, exécuter diverses procédures mathématiques comme l'ajustement, etc.

Après avoir chargé "html5csv.js", le problème de l'analyse d'un tableau et de la création d'un CSV est un jeu d'enfant :

CSV.begin('#PrintDiv').download('MyData.csv').go();

Voici un Démonstration JSFiddle de votre exemple avec ce code .

En interne, pour Firefox/Chrome, il s'agit d'une solution orientée URL de données, similaire à celle proposée par @italo, @lepe, et @adeneo (sur une autre question). Pour IE

El CSV.begin() configure le système pour lire les données dans un tableau interne. Cette lecture a alors lieu. Ensuite, l'appel .download() génère un lien URL de données en interne et le clique avec un link-clicker. Cela envoie un fichier à l'utilisateur final.

Selon caniuse IE10 ne supporte pas <a download=...> . Ainsi, pour IE, ma bibliothèque appelle navigator.msSaveBlob() en interne, comme suggéré par @Manu Sharma

0 votes

@IanLim J'ai incorporé la technique dans le lien SO ci-dessus et je peux confirmer que la bibliothèque html5csv génère maintenant des fichiers csv dans IE11.

5voto

mplungjan Points 36458

En voici deux SOLUTIONS DE RECHANGE au problème du déclenchement des téléchargements à partir du client uniquement. Dans les navigateurs plus récents, vous devriez regarder "blob".


1. Faites glisser et déposez le tableau

Saviez-vous que vous pouvez simplement faire glisser votre tableau dans Excel ?

Voici comment sélectionner le tableau pour le couper et le coller ou le faire glisser.

Sélectionner un tableau complet avec Javascript (à copier dans le presse-papiers)


2. Créez une page popup à partir de votre div.

Bien qu'il ne pas produire de dialogue de sauvegarde si le résultant Le popup est enregistré avec l'extension .csv il sera traité correctement par Excel.

La chaîne pourrait être
w.document.write("row1.1\trow1.2\trow1.3\nrow2.1\trow2.2\trow2.3");
par exemple, délimité par des tabulations avec un saut de ligne pour les lignes.

Il existe des plugins qui créeront la chaîne de caractères pour vous - tels que http://plugins.jquery.com/project/table2csv

var w = window.open('','csvWindow'); // popup, may be blocked though
// the following line does not actually do anything interesting with the 
// parameter given in current browsers, but really should have. 
// Maybe in some browser it will. It does not hurt anyway to give the mime type
w.document.open("text/csv");
w.document.write(csvstring); // the csv string from for example a jquery plugin
w.document.close();

CLAUSE DE NON-RESPONSABILITÉ : Ce sont des solutions de contournement, et ne répondent pas complètement à la question qui a actuellement la réponse pour la plupart des navigateurs : pas possible sur le client uniquement.

4 votes

Et à nouveau un vote négatif non commenté. Un geste sans valeur si vous ne commentez pas !

1 votes

Une fois que vous avez obtenu vos données CSV, vous pouvez créer a con download="myfile.csv" y type="text/csv" encoder les données CSV en base64 à l'aide des attributs suivants btoa et définir les src de l'attribut "data:text/csv;base64,P2ZyB4bW.....xucz0===" , ajoutez le a au DOM (le cacher) et cliquez dessus, le fichier sera téléchargé.

0 votes

Oui, je sais, répondu dans une autre réponse sur cette page.

4voto

DKSan Points 2545

En utilisant uniquement jQuery, vous ne pouvez pas éviter un appel au serveur.

Cependant, pour obtenir ce résultat, j'utilise Downloadify qui me permet de sauvegarder des fichiers sans avoir à faire un autre appel au serveur. Cela permet de réduire la charge du serveur et d'offrir une bonne expérience utilisateur.

Pour obtenir un CSV correct, il suffit de supprimer toutes les balises inutiles et de mettre un "," entre les données.

8 votes

Cette chose aura besoin de Flash, donc elle ne sera pas portable sur tous les navigateurs, vérifiez la réponse ci-dessous avec les HREFs alimentés par data:application. Simple, propre.

0 votes

En plus de nécessiter Flash, cette solution ne respecte pas les exigences de la question : utiliser jQuery et éviter l'appel au serveur.

0 votes

Eh bien, Pratik a dit côté client et éviter l'appel au serveur. La portabilité n'est pas toujours importante. Si cela correspond à ses besoins, pourquoi pas.

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