3
votes

Téléchargement d'un fichier CSV à l'aide de Vue et JS

J'ai un champ appelé csvdata qui contient un tableau du format suivant:

<button type="button" class="btn btn-info action_btn" v-on:click="downloadCSVData">
      Download
</button>

J'essaye de télécharger un fichier CSV de ces données. J'utilise Vue donc ça ressemble à:

[
    [1,2,3],
    [4,5,6],
    [7,8,9]
]

À quoi doit ressembler la fonction downloadCSVData ?


1 commentaires

vous avez besoin d'un langage de script backend tel que PHP pour traiter ce tableau en un fichier téléchargeable.


3 Réponses :


0
votes

Voici le code de travail pour télécharger un fichier csv en vue

Cet exemple de code convertit un tableau d'objets en un fichier csv parfait avec des en-têtes appelez la fonction exportCSVFile (headers, items, fileTitle)

headers = {name: 'Name' // nom de colonne formaté, age: 'Age'}

items = [{nom: 'Joo', âge: 21}, {nom: 'fourmi', âge: 20}]

filename = 'somefilename.csv'

function downloadCSVData () {
    var array = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
    ];
    var str = '';
    for (var i = 0; i < array.length; i++) { 
    let line = '';
    line = array[i].join(",");
    str += line + '\r\n';
    }
    var blob = new Blob([str], { type: 'text/csv;charset=utf-8;' });

    var link = document.createElement('a');
    var url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', 'csvfilename.csv');
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

Si la valeur donnée est un tableau 2d, utilisez simplement cette fonction

function convertToCSV(objArray) {
  const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;
  let str = '';
  for (let i = 0; i < array.length; i++) { // eslint-disable-line
    let line = '';
    for (const index in array[i]) { // eslint-disable-line
      if (line !== '') line += ',';
      line += array[i][index];
    }
    str += line + '\r\n'; // eslint-disable-line
  }
  return str;
}

function exportCSVFile(headers, items, fileTitle) {
  if (headers) {
    items.unshift(headers);
  }
  const jsonObject = JSON.stringify(items);
  const csv = convertToCSV(jsonObject);
  const exportedFilenmae = fileTitle + '.csv' || 'export.csv'; // eslint-disable-line
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
  if (navigator.msSaveBlob) { // IE 10+
    navigator.msSaveBlob(blob, exportedFilenmae);
  } else {
    const link = document.createElement('a');
    if (link.download !== undefined) {
      const url = URL.createObjectURL(blob);
      link.setAttribute('href', url);
      link.setAttribute('download', exportedFilenmae);
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  }
}

export default exportCSVFile;


0 commentaires

4
votes

Je pense que vous pouvez créer une méthode comme celle-ci, en supposant que csvdata est une propriété de données accessible par this dans votre composant Vue:

downloadCSVData() => {
    let csv = 'Put,Column,Titles,Here\n';
    this.csvdata.forEach((row) => {
            csv += row.join(',');
            csv += "\n";
    });
 
    const anchor = document.createElement('a');
    anchor.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
    anchor.target = '_blank';
    anchor.download = 'nameYourFileHere.csv';
    anchor.click();
}


2 commentaires

encodeURI a fonctionné pour une petite quantité de données (~ 2 lignes de 8 colonnes). Mais suivre cela avec encodeURIComponent a fonctionné pour beaucoup plus de données.


@JoshMorel vous avez raison. Je mettrai à jour ma réponse. Voici une documentation sur la différence: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...



1
votes
  1. Convertissez le tableau en texte. ( let data = [[1,2,3], [4,5,6], [7,8,9]].join('\r\n').toString() )
  2. Convertissez le texte en base64. ( let encoded_data = btoa(data) )
  3. Créez un iFrame et définissez son src = les données encodées. let iframe = document.createElement('iframe'); iframe.src = "data:application/octet-stream;base64," + encoded_data
  4. Ajoutez l'iframe au corps du document.body.appendChild(iframe) : document.body.appendChild(iframe) .

Il y a cependant quelques inconvénients à cette approche:

  1. La politique de sécurité du contenu peut bloquer l'étape 4. Vous avez le contrôle sur CSP dans votre page, mais ne sacrifiez pas la sécurité pour un code simple.
  2. Le fichier sera toujours nommé "téléchargement" sans extension de fichier.

Une meilleure approche serait de créer un fichier temporaire sur le serveur et de fournir à l'utilisateur un lien vers ce fichier.


0 commentaires