web-dev-qa-db-fra.com

Tableau JavaScript au format CSV

J'ai suivi cet article Comment exporter des informations de tableau JavaScript vers CSV (côté client)? pour obtenir un tableau JS imbriqué écrit en tant que fichier CSV.

Le tableau ressemble à:

var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];

Le code indiqué dans le lien fonctionne bien, sauf qu'après la troisième ligne du fichier csv, le reste des valeurs se trouve sur la même ligne E.g.

nom1,2,3
name2,4,5
name3,6,7
name4,8,9name5,10,11 etc etc

Quelqu'un peut-il nous expliquer pourquoi? Même en utilisant Chrome ou FF.

Merci

MODIFIER

jsfiddle http://jsfiddle.net/iaingallagher/dJKz6/

Iain

29
duff

La réponse citée était fausse. Tu devais changer

csvContent += index < infoArray.length ? dataString+ "\n" : dataString;

à

csvContent += dataString + "\n";

BTW, le code cité est sous-optimal. Vous devriez éviter d'ajouter plusieurs fois à une chaîne. Vous devriez plutôt ajouter à un tableau et faire un tableau.join ("\ n") à la fin. Comme ça:

var lineArray = [];
data.forEach(function (infoArray, index) {
    var line = infoArray.join(",");
    lineArray.Push(index == 0 ? "data:text/csv;charset=utf-8," + line : line);
});
var csvContent = lineArray.join("\n");

Pour ce qui est de savoir pourquoi la réponse citée était fausse (ce qui est drôle a été accepté!): index, le deuxième paramètre de la fonction de rappel forEach, est l’index du tableau en boucle et il n’a aucun sens de le comparer à la taille de infoArray, qui est un élément dudit tableau (qui se trouve être aussi un tableau).

72
Walter Tross

La forme générale est:

var ids = []; <= this is your array/collection
var csv = ids.join(",");

Pour votre cas, vous devrez vous adapter un peu

11
Mircea Stanciu

J'ai créé ce code pour créer un fichier csv lisible et agréable:

var objectToCSVRow = function(dataObject) {
    var dataArray = new Array;
    for (var o in dataObject) {
        var innerValue = dataObject[o]===null?'':dataObject[o].toString();
        var result = innerValue.replace(/"/g, '""');
        result = '"' + result + '"';
        dataArray.Push(result);
    }
    return dataArray.join(' ') + '\r\n';
}

var exportToCSV = function(arrayOfObjects) {

    if (!arrayOfObjects.length) {
        return;
    }

    var csvContent = "data:text/csv;charset=utf-8,";

    // headers
    csvContent += objectToCSVRow(Object.keys(arrayOfObjects[0]));

    arrayOfObjects.forEach(function(item){
        csvContent += objectToCSVRow(item);
    }); 

    var encodedUri = encodeURI(csvContent);
    var link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "customers.csv");
    document.body.appendChild(link); // Required for FF
    link.click();
    document.body.removeChild(link); 
}

Dans votre cas, puisque vous utilisez des tableaux dans tableau plutôt que des objets dans tableau, vous allez ignorer la partie en-tête, mais vous pouvez ajouter les noms de colonne vous-même en mettant ceci à la place de cette partie:

// headers
csvContent += '"Column name 1" "Column name 2" "Column name 3"\n';

Le secret est qu'un espace sépare les colonnes du fichier csv, et nous plaçons les valeurs de colonne dans les guillemets doubles pour permettre les espaces, et nous échappons des guillemets doubles dans les valeurs elles-mêmes.

Notez également que je remplace les valeurs null par une chaîne vide, car cela répondait à mes besoins, mais vous pouvez le modifier et le remplacer par tout ce que vous voulez.

9
Frane Poljak

pour un simple csv, un map () et un join () suffisent:

var csv = test_array.map(function(d){
    return d.join();
}).join('\n');

/* Results in 
name1,2,3
name2,4,5
name3,6,7
name4,8,9
name5,10,11

Cette méthode vous permet également de spécifier un séparateur de colonne autre qu'une virgule dans la join intérieure. par exemple un onglet: d.join('\t')

D'autre part, si vous voulez le faire correctement et mettre les chaînes entre guillemets "", vous pouvez utiliser la magie JSON:

var csv = test_array.map(function(d){
   return JSON.stringify(d);
})
.join('\n') 
.replace(/(^\[)|(\]$)/mg, ''); // remove opening [ and closing ] brackets from each line 

/* would produce
"name1",2,3
"name2",4,5
"name3",6,7
"name4",8,9
"name5",10,11

si vous avez un tableau d'objets comme:

var data = [
  {"title": "Book title 1", "author": "Name1 Surname1"},
  {"title": "Book title 2", "author": "Name2 Surname2"},
  {"title": "Book title 3", "author": "Name3 Surname3"},
  {"title": "Book title 4", "author": "Name4 Surname4"}
];

// use
var csv = data.map(function(d){
    return JSON.stringify(values(d));
})
.join('\n') 
.replace(/(^\[)|(\]$)/mg, '');
5
Konstantin

Si vos données contiennent des nouvelles lignes ou des virgules, vous devez d'abord les échapper:

const escape = text =>
    text.replace(/\\/g, "\\\\")
        .replace(/\n/g, "\\n")
        .replace(/,/g, "\\,")

escaped_array = test_array.map(fields => fields.map(escape))

Alors faites simplement:

csv = escaped_array.map(fields => fields.join(","))
                .join("\n")

Si vous voulez le rendre téléchargeable dans le navigateur:

dl = "data:text/csv;charset=utf-8," + csv
window.open(encodeURI(dl))
3
Zaz

La réponse choisie est probablement correcte mais elle semble inutilement incertaine.

J'ai trouvé Fiddle de Shomz très utile, mais là encore, inutilement obscur. (Edit: je vois maintenant que Fiddle est basé sur le violon du PO.)

Voici ma version (pour laquelle j'ai créé un Fiddle pour) que je pense plus claire:

function downloadableCSV(rows) {
  var content = "data:text/csv;charset=utf-8,";

  rows.forEach(function(row, index) {
    content += row.join(",") + "\n";
  });

  return encodeURI(content);
}

var rows = [
  ["name1", 2, 3],
  ["name2", 4, 5],
  ["name3", 6, 7],
  ["name4", 8, 9],
  ["name5", 10, 11]
];

$("#download").click(function() {
  window.open(downloadableCSV(rows));
});
0
Jason Swett