226 votes

Comment lire les données d'un fichier *.CSV en utilisant javascript ?

Mes données csv ressemblent à ceci :

rubrique1,rubrique2,rubrique3,rubrique4,rubrique5,valeur1_1,valeur2_1,valeur3_1,valeur4_1,valeur5_1,valeur1_2,valeur2_2,valeur3_2,valeur4_2,valeur5_2....

Comment lire ces données et convertir un tableau comme celui-ci :

[rubrique1:valeur1_1 , rubrique2:valeur2_1, rubrique3 : valeur3_1, rubrique4 valeur4_1, rubrique5 : valeur5_1 ], [rubrique1:valeur1_2 , rubrique2:valeur2_2, rubrique3 : valeur3_2, rubrique4 : valeur4_2, rubrique5 : valeur5_2 ]....

Utilisation de javascript ? J'ai essayé ce code mais pas de chance :

<script type="text/javascript">
    var allText =[];
    var allTextLines = [];
    var Lines = [];

    var txtFile = new XMLHttpRequest();
    txtFile.open("GET", "file://d:/data.txt", true);
    txtFile.onreadystatechange = function()
    {
        allText = txtFile.responseText;
        allTextLines = allText.split(/\r\n|\n/);
    };

    document.write(allTextLines);<br>
    document.write(allText);<br>
    document.write(txtFile);<br>
</script>

0 votes

Sans retour à la ligne dans votre fichier CSV, il sera impossible pour tout code JavaScript de savoir où s'arrête un tableau (ou un objet) et où commence l'autre (sauf si vous savez à l'avance qu'il y a toujours exactement cinq rubriques). S'agit-il d'un oubli de copier-coller ?

0 votes

Oui, je sais d'avance qu'il y a exactement cinq champs.

1 votes

Question suivante : jQuery est-il autorisé dans la solution ? Vous avez utilisé la balise mais votre exemple de code est purement JavaScript.

229voto

Evan Plaice Points 5677

Pas besoin d'écrire votre propre...

Le site jQuery-CSV possède une fonction appelée $.csv.toObjects(csv) qui effectue le mappage automatiquement.

Remarque : La bibliothèque est conçue pour traiter toutes les données CSV qui sont RFC 4180 y compris tous les cas extrêmes que la plupart des solutions "simples" négligent.

Comme @Blazemonger l'a déjà dit, vous devez d'abord ajouter des sauts de ligne pour rendre les données CSV valides.

En utilisant l'ensemble de données suivant :

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

Utilisez le code :

var data = $.csv.toObjects(csv):

La sortie enregistrée dans 'data' sera :

[
  { heading1:"value1_1",heading2:"value2_1",heading3:"value3_1",heading4:"value4_1",heading5:"value5_1" } 
  { heading1:"value1_2",heading2:"value2_2",heading3:"value3_2",heading4:"value4_2",heading5:"value5_2" }
]

Remarque : techniquement, la façon dont vous avez écrit le mappage clé-valeur est du JavaScript non valide. Les objets contenant les paires clé-valeur doivent être entourés de parenthèses.

Si vous voulez l'essayer par vous-même, je vous suggère de jeter un coup d'œil à l'application Démonstration de l'utilisation de base sous l'onglet "toObjects()".

Disclaimer : Je suis l'auteur original de jQuery-CSV.

Mise à jour :

Modifié pour utiliser l'ensemble de données que l'op a fourni et inclus un lien vers la démo où les données peuvent être testées pour la validité.

3 votes

Autrement dit, "toObject" est ou peut être considéré comme "toJSON", non ? Et, est-ce que les deux points qui suivent l'appel à toObjects(csv) sont une faute de frappe ? Ne devrait-il pas s'agir d'un point-virgule ?

0 votes

@ClayShannon toJSON() (ie JSON.stringify()) implique que les données CSV sont analysées et produites au format chaîne (ie text/json). toObjects fait en fait correspondre le CSV en mémoire comme un tableau d'objets où les noms de colonnes sont utilisés comme noms de clés. $.csv.toObjects() est l'équivalent CSV de JSON.parse(). La sortie ci-dessus est juste une simplification de ce à quoi les données ressembleraient en mémoire.

11 votes

Une bibliothèque fantastique. Pour info, le paramètre csv passed est une chaîne csv - lisez le fichier csv en tant que texte pour obtenir la chaîne csv.

133voto

Blazemonger Points 39230

NOTE : J'ai concocté cette solution avant qu'on me rappelle tous les "cas spéciaux" qui peuvent se produire dans un fichier CSV valide, comme les guillemets échappés. Je laisse ma réponse pour ceux qui veulent quelque chose de rapide et sale, mais je recommande Réponse d'Evan pour la précision.


Ce code fonctionnera lorsque votre data.txt est une longue chaîne d'entrées séparées par des virgules, sans nouvelle ligne :

données.txt :

 heading1,heading2,heading3,heading4,heading5,value1_1,...,value5_2

javascript :

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var record_num = 5;  // or however many elements there are in each row
    var allTextLines = allText.split(/\r\n|\n/);
    var entries = allTextLines[0].split(',');
    var lines = [];

    var headings = entries.splice(0,record_num);
    while (entries.length>0) {
        var tarr = [];
        for (var j=0; j<record_num; j++) {
            tarr.push(headings[j]+":"+entries.shift());
        }
        lines.push(tarr);
    }
    // alert(lines);
}

Le code suivant fonctionnera sur un "vrai" fichier CSV avec des sauts de ligne entre chaque série d'enregistrements :

données.txt :

heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2

javascript :

$(document).ready(function() {
    $.ajax({
        type: "GET",
        url: "data.txt",
        dataType: "text",
        success: function(data) {processData(data);}
     });
});

function processData(allText) {
    var allTextLines = allText.split(/\r\n|\n/);
    var headers = allTextLines[0].split(',');
    var lines = [];

    for (var i=1; i<allTextLines.length; i++) {
        var data = allTextLines[i].split(',');
        if (data.length == headers.length) {

            var tarr = [];
            for (var j=0; j<headers.length; j++) {
                tarr.push(headers[j]+":"+data[j]);
            }
            lines.push(tarr);
        }
    }
    // alert(lines);
}

http://jsfiddle.net/mblase75/dcqxr/

4 votes

Au fait, cela suppose que le fichier CSV comporte en fait plusieurs lignes -- c'est ce que la fonction allText.split(/\r\n|\n/) se divise. Si toutes vos données sont en fait une longue chaîne de données séparées par des virgules, sans aucune nouvelle ligne, il ne s'agit pas d'un véritable fichier CSV.

1 votes

Bonjour, j'ai utilisé ce code : Mais il n'y a pas de sortie. Juste une alerte vide affichée. Mon fichier ressemble à : heading1,heading2,heading3,heading4,heading5,value1_1,value2_1,value3_1,value4_1,value5_1,value1_2,value2_2,value3_2,value4_2,value5_2 Les deux csv.html et data.txt sont dans le même dossier.

0 votes

Si ce n'est pas le bon fichier (ou les bonnes données), à quoi devrait ressembler mon fichier ?

91voto

Matt Points 5202

Ne vous séparez pas des virgules -- cela ne fonctionnera pas pour la plupart des fichiers CSV, et cette question a beaucoup trop de vues pour que le type de données d'entrée du demandeur s'applique à tout le monde. L'analyse du CSV est un peu effrayante car il n'y a pas de norme officielle, et beaucoup d'auteurs de texte délimité ne prennent pas en compte les cas limites.

Cette question est ancienne, mais je crois qu'il y a une meilleure solution maintenant que Papa Parse est disponible. C'est une bibliothèque que j'ai écrite, avec l'aide de contributeurs, qui analyse les textes ou les fichiers CSV. C'est la seule bibliothèque JS que je connaisse qui supporte des fichiers de plusieurs gigaoctets. Elle gère également les entrées malformées de manière élégante.

Fichier de 1 Go analysé en 1 minute : Parsed 1 GB file in 1 minute

L'analyse syntaxique du texte est très facile :

var data = Papa.parse(csvString);

L'analyse des fichiers est également facile :

Papa.parse(file, {
    complete: function(results) {
        console.log(results);
    }
});

Le streaming de fichiers est similaire (voici un exemple de streaming d'un fichier distant) :

Papa.parse("http://example.com/bigfoo.csv", {
    download: true,
    step: function(row) {
        console.log("Row:", row.data);
    },
    complete: function() {
        console.log("All done!");
    }
});

Si votre page Web se bloque pendant l'analyse syntaxique, Papa peut utiliser des travailleurs Web pour que votre site Web reste réactif.

Papa peut détecter automatiquement les délimiteurs et faire correspondre les valeurs aux colonnes d'en-tête, si une ligne d'en-tête est présente. Il peut également transformer les valeurs numériques en types de nombres réels. Il analyse de manière appropriée les sauts de ligne, les guillemets et autres situations étranges, et gère même les entrées malformées de manière aussi robuste que possible. Je me suis inspiré de bibliothèques existantes pour faire Papa, alors félicitations aux autres implémentations JS.

0 votes

Papa est facile à utiliser et rapide ! Merci !

0 votes

+1 Bon travail sur Papa Parse. J'aimerais l'étudier en détail un jour pour voir comment vous avez géré les gros fichiers et le streaming. Je suis très heureux de voir d'autres développeurs écrire des parsers complets qui reprennent là où jquery-csv s'est arrêté.

3 votes

@EvanPlaice Merci. Vous pourriez aimer cette présentation que j'ai donnée hier soir à un meetup local : docs.google.com/presentation/d/

6voto

curran Points 141

Voici une fonction JavaScript qui analyse les données CSV en tenant compte des virgules présentes dans les guillemets.

// Parse a CSV row, accounting for commas inside quotes                   
function parse(row){
  var insideQuote = false,                                             
      entries = [],                                                    
      entry = [];
  row.split('').forEach(function (character) {                         
    if(character === '"') {
      insideQuote = !insideQuote;                                      
    } else {
      if(character == "," && !insideQuote) {                           
        entries.push(entry.join(''));                                  
        entry = [];                                                    
      } else {
        entry.push(character);                                         
      }                                                                
    }                                                                  
  });
  entries.push(entry.join(''));                                        
  return entries;                                                      
}

Exemple d'utilisation de la fonction pour analyser un fichier CSV qui ressemble à ceci :

"foo, the column",bar
2,3
"4, the value",5

en tableaux :

// csv could contain the content read from a csv file
var csv = '"foo, the column",bar\n2,3\n"4, the value",5',

    // Split the input into lines
    lines = csv.split('\n'),

    // Extract column names from the first line
    columnNamesLine = lines[0],
    columnNames = parse(columnNamesLine),

    // Extract data from subsequent lines
    dataLines = lines.slice(1),
    data = dataLines.map(parse);

// Prints ["foo, the column","bar"]
console.log(JSON.stringify(columnNames));

// Prints [["2","3"],["4, the value","5"]]
console.log(JSON.stringify(data));

Voici comment vous pouvez transformer les données en objets, par exemple L'analyseur csv de D3 (qui est une solution tierce solide) :

var dataObjects = data.map(function (arr) {
  var dataObject = {};
  columnNames.forEach(function(columnName, i){
    dataObject[columnName] = arr[i];
  });
  return dataObject;
});

// Prints [{"foo":"2","bar":"3"},{"foo":"4","bar":"5"}]
console.log(JSON.stringify(dataObjects));

Voici un bricolage de ce code .

Profitez-en ! -- Curran

2voto

ajkochanowicz Points 1763

Selon la réponse acceptée,

J'ai réussi à le faire fonctionner en changeant le 1 par un 0 ici :

for (var i=1; i<allTextLines.length; i++) {

changé en

for (var i=0; i<allTextLines.length; i++) {

Il calculera un fichier avec une seule ligne continue comme ayant une longueur allTextLines.length de 1. Donc, si la boucle commence à 1 et se déroule tant qu'elle est inférieure à 1, elle ne se déroule jamais. D'où la boîte d'alerte vide.

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