Código Javascript para analizar datos CSV


215

¿Alguien tiene una idea de dónde podría encontrar algún código javascript para analizar los datos CSV?


3
Eche un vistazo a esta respuesta aquí, tiene buenas respuestas: stackoverflow.com/questions/8493195/…
Dobes Vandermeer

14
La mayoría de las respuestas a continuación son incorrectas, aparte de la de Andy. Cualquier respuesta que use la coincidencia de patrones o las divisiones está condenada al fracaso; no admitirán secuencias de escape. Para eso, necesita una máquina de estados finitos.
greg.kindel

3
Analizando un archivo CSV local con JavaScript y Papa Parse: joyofdata.de/blog/…
Raffael

44
Papa Parse es otra opción con muchas características (multihilo, soporte de fila de encabezado, delimitador de detección automática y más)
Hinrich

1
Otro voto para PapaParse, lo estoy usando con AngularJS y funciona muy bien.
Dmitry Buslaev

Respuestas:


257

Puede usar la función CSVToArray () mencionada en esta entrada de blog.

<script type="text/javascript">
    // ref: http://stackoverflow.com/a/1293163/2343
    // This will parse a delimited string into an array of
    // arrays. The default delimiter is the comma, but this
    // can be overriden in the second argument.
    function CSVToArray( strData, strDelimiter ){
        // Check to see if the delimiter is defined. If not,
        // then default to comma.
        strDelimiter = (strDelimiter || ",");

        // Create a regular expression to parse the CSV values.
        var objPattern = new RegExp(
            (
                // Delimiters.
                "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

                // Quoted fields.
                "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

                // Standard fields.
                "([^\"\\" + strDelimiter + "\\r\\n]*))"
            ),
            "gi"
            );


        // Create an array to hold our data. Give the array
        // a default empty first row.
        var arrData = [[]];

        // Create an array to hold our individual pattern
        // matching groups.
        var arrMatches = null;


        // Keep looping over the regular expression matches
        // until we can no longer find a match.
        while (arrMatches = objPattern.exec( strData )){

            // Get the delimiter that was found.
            var strMatchedDelimiter = arrMatches[ 1 ];

            // Check to see if the given delimiter has a length
            // (is not the start of string) and if it matches
            // field delimiter. If id does not, then we know
            // that this delimiter is a row delimiter.
            if (
                strMatchedDelimiter.length &&
                strMatchedDelimiter !== strDelimiter
                ){

                // Since we have reached a new row of data,
                // add an empty row to our data array.
                arrData.push( [] );

            }

            var strMatchedValue;

            // Now that we have our delimiter out of the way,
            // let's check to see which kind of value we
            // captured (quoted or unquoted).
            if (arrMatches[ 2 ]){

                // We found a quoted value. When we capture
                // this value, unescape any double quotes.
                strMatchedValue = arrMatches[ 2 ].replace(
                    new RegExp( "\"\"", "g" ),
                    "\""
                    );

            } else {

                // We found a non-quoted value.
                strMatchedValue = arrMatches[ 3 ];

            }


            // Now that we have our value string, let's add
            // it to the data array.
            arrData[ arrData.length - 1 ].push( strMatchedValue );
        }

        // Return the parsed data.
        return( arrData );
    }

</script>

1
Esto puede manejar comas incrustadas, comillas y saltos de línea, por ejemplo: var csv = 'id, value \ n1, James \ n02, "Jimmy Smith, Esq." \ N003, "James" "Jimmy" "Smith, III" \ n0004, "James \ nSmith \ nWuz Here" 'var array = CSVToArray (csv, ",");
prototipo

44
Da undefinedpara los campos vacíos que se cita . Ejemplo: CSVToArray("4,,6")me da [["4","","6"]], pero CSVToArray("4,\"\",6")me da [["4",undefined,"6"]].
Pang

3
He tenido problemas con esto en Firefox, y el script no responde. Parecía que sólo afectará a unos pocos usuarios, sin embargo, por lo que no pudo encontrar la causa
JDandChips

8
Hay un error en la expresión regular: "([^\"\\"debería ser "([^\\". De lo contrario, una comilla doble en cualquier parte de un valor sin comillas lo terminará prematuramente. Encontré esto de la manera difícil ...
Walter Tross

55
Para cualquiera que busque una versión reducida del método anterior, con la corrección regex descrita anteriormente aplicada: gist.github.com/Jezternz/c8e9fafc2c114e079829974e3764db75
Josh Mc

147

jQuery-CSV

Es un complemento jquery diseñado para funcionar como una solución de extremo a extremo para analizar CSV en datos Javascript. Maneja todas las mayúsculas y minúsculas presentadas en RFC 4180 , así como algunas que aparecen para las exportaciones de Excel / Google Spreadsheed (es decir, en su mayoría con valores nulos) que falta la especificación.

Ejemplo:

pista, artista, álbum, año

Peligroso, 'Busta Rhymes', 'When Disaster Strikes', 1997

// calling this
music = $.csv.toArrays(csv)

// outputs...
[
  ["track","artist","album","year"],
  ["Dangerous","Busta Rhymes","When Disaster Strikes","1997"]
]

console.log(music[1][2]) // outputs: 'When Disaster Strikes'

Actualizar:

Ah sí, probablemente también debería mencionar que es completamente configurable.

music = $.csv.toArrays(csv, {
  delimiter:"'", // sets a custom value delimiter character
  separator:';', // sets a custom field separator character
});

Actualización 2:

Ahora también funciona con jQuery en Node.js. Por lo tanto, tiene la opción de realizar un análisis del lado del cliente o del lado del servidor con la misma biblioteca.

Actualización 3:

Desde el cierre de Google Code, jquery-csv se ha migrado a GitHub .

Descargo de responsabilidad: también soy el autor de jQuery-CSV.


29
¿Por qué es jQuery csv? ¿Por qué depende de jQuery? He tenido una exploración rápida a través de la fuente ... no se ve como si estuvieras usando jQuery
paulslater19

17
@ paulslater19 El complemento no depende de jquery. Más bien, sigue las pautas comunes de desarrollo de jQuery. Todos los métodos incluidos son estáticos y residen bajo su propio espacio de nombres (es decir, $ .csv). Para usarlos sin jQuery, simplemente cree un objeto global $ al que se unirá el complemento durante la inicialización.
Evan Plaice

2
está csven el código de la solución consulte el .csv filename? Estoy interesado en una buena herramienta JS / JQuery para analizar un archivo csv
bouncingHippo

1
@bouncingHippo En el ejemplo solo se refiere a una cadena de datos csv, pero la lib se puede usar para abrir archivos csv localmente en el navegador utilizando la API de archivos HTML5. Aquí hay un ejemplo de ello en acción jquery-csv.googlecode.com/git/examples/file-handling.html .
Evan Plaice el

1
Dado que no depende de jQuery, sería mejor eliminar la dependencia global "$" y permitir a los usuarios pasar cualquier referencia de objeto que deseen. Quizás por defecto a jQuery si está disponible. Hay otras bibliotecas que usan "$" y podrían ser utilizadas por equipos de desarrollo con un mínimo de representantes de esas bibliotecas.
RobG

40

Tengo una implementacion como parte de un proyecto de hoja de cálculo.

Este código aún no se ha probado exhaustivamente, pero cualquiera puede usarlo.

Sin embargo, como se señaló en algunas de las respuestas, su implementación puede ser mucho más simple si realmente tiene un archivo DSV o TSV , ya que no permiten el uso de los separadores de registros y campos en los valores. CSV, por otro lado, en realidad puede tener comas y líneas nuevas dentro de un campo, lo que rompe la mayoría de los enfoques basados ​​en expresiones regulares y divididas.

var CSV = {
parse: function(csv, reviver) {
    reviver = reviver || function(r, c, v) { return v; };
    var chars = csv.split(''), c = 0, cc = chars.length, start, end, table = [], row;
    while (c < cc) {
        table.push(row = []);
        while (c < cc && '\r' !== chars[c] && '\n' !== chars[c]) {
            start = end = c;
            if ('"' === chars[c]){
                start = end = ++c;
                while (c < cc) {
                    if ('"' === chars[c]) {
                        if ('"' !== chars[c+1]) { break; }
                        else { chars[++c] = ''; } // unescape ""
                    }
                    end = ++c;
                }
                if ('"' === chars[c]) { ++c; }
                while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) { ++c; }
            } else {
                while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) { end = ++c; }
            }
            row.push(reviver(table.length-1, row.length, chars.slice(start, end).join('')));
            if (',' === chars[c]) { ++c; }
        }
        if ('\r' === chars[c]) { ++c; }
        if ('\n' === chars[c]) { ++c; }
    }
    return table;
},

stringify: function(table, replacer) {
    replacer = replacer || function(r, c, v) { return v; };
    var csv = '', c, cc, r, rr = table.length, cell;
    for (r = 0; r < rr; ++r) {
        if (r) { csv += '\r\n'; }
        for (c = 0, cc = table[r].length; c < cc; ++c) {
            if (c) { csv += ','; }
            cell = replacer(r, c, table[r][c]);
            if (/[,\r\n"]/.test(cell)) { cell = '"' + cell.replace(/"/g, '""') + '"'; }
            csv += (cell || 0 === cell) ? cell : '';
        }
    }
    return csv;
}
};

99
Esta es una de mis respuestas favoritas. Es un analizador real implementado en no mucho código.
Trevor Dixon

1
Si se coloca una coma al final de una línea, una celda vacía debe seguirla. Este código simplemente salta a la siguiente línea, dando como resultado una undefinedcelda. Por ejemplo,console.log(CSV.parse("first,last,age\r\njohn,doe,"));
skibulk

Además, las celdas vacías deben analizarse en cadenas vacías. Este código los analiza en ceros, lo cual es confuso ya que las celdas pueden contener ceros:console.log(CSV.parse("0,,2,3"));
skibulk

@skibulk Su segundo comentario es incorrecto (al menos en Chrome funciona bien con su ejemplo). Sin embargo, su primer comentario es válido, aunque se arregla fácilmente: agregue lo siguiente justo antes if ('\r' === chars[c]) { ... }:if (end === c-1) { row.push(reviver(table.length-1, row.length, '')); }
coderforlife

35

Aquí hay un analizador CSV extremadamente simple que maneja los campos entre comillas, nuevas líneas y comillas dobles. No hay división ni RegEx. Escanea la cadena de entrada de 1 a 2 caracteres a la vez y crea una matriz.

Pruébelo en http://jsfiddle.net/vHKYH/ .

function parseCSV(str) {
    var arr = [];
    var quote = false;  // true means we're inside a quoted field

    // iterate over each character, keep track of current row and column (of the returned array)
    for (var row = 0, col = 0, c = 0; c < str.length; c++) {
        var cc = str[c], nc = str[c+1];        // current character, next character
        arr[row] = arr[row] || [];             // create a new row if necessary
        arr[row][col] = arr[row][col] || '';   // create a new column (start with empty string) if necessary

        // If the current character is a quotation mark, and we're inside a
        // quoted field, and the next character is also a quotation mark,
        // add a quotation mark to the current column and skip the next character
        if (cc == '"' && quote && nc == '"') { arr[row][col] += cc; ++c; continue; }  

        // If it's just one quotation mark, begin/end quoted field
        if (cc == '"') { quote = !quote; continue; }

        // If it's a comma and we're not in a quoted field, move on to the next column
        if (cc == ',' && !quote) { ++col; continue; }

        // If it's a newline (CRLF) and we're not in a quoted field, skip the next character
        // and move on to the next row and move to column 0 of that new row
        if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; }

        // If it's a newline (LF or CR) and we're not in a quoted field,
        // move on to the next row and move to column 0 of that new row
        if (cc == '\n' && !quote) { ++row; col = 0; continue; }
        if (cc == '\r' && !quote) { ++row; col = 0; continue; }

        // Otherwise, append the current character to the current column
        arr[row][col] += cc;
    }
    return arr;
}

Es simple y funciona para mí, lo único que cambié fue agregar un recorte () al valor :)
JustEngland

3
Esto parece más limpio y más sencillo. Tuve que analizar un archivo de 4 MB y las otras respuestas se bloquearon en ie8, pero esto lo logró.
Charles Clayton

3
Esto también funcionó para mí. Sin embargo, tuve que hacer una modificación para permitir el manejo adecuado de los if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc == '\n' && !quote) { ++row; col = 0; continue; }
avances

1
Otro usuario (@ sorin-postelnicu) publicó útilmente una función complementaria para convertir el resultado en un objeto de diccionario: jsfiddle.net/8t2po6wh .
Trevor Dixon

1
Sí, cada vez que se necesita velocidad o las huellas de memoria son importantes, una solución limpia como esta es muy superior. El análisis de máquina de estados es mucho más fluido.
Tatarizar el

14

Aquí está mi gramática PEG (.js) que parece funcionar bien en RFC 4180 (es decir, maneja los ejemplos en http://en.wikipedia.org/wiki/Comma-separated_values ):

start
  = [\n\r]* first:line rest:([\n\r]+ data:line { return data; })* [\n\r]* { rest.unshift(first); return rest; }

line
  = first:field rest:("," text:field { return text; })*
    & { return !!first || rest.length; } // ignore blank lines
    { rest.unshift(first); return rest; }

field
  = '"' text:char* '"' { return text.join(''); }
  / text:[^\n\r,]* { return text.join(''); }

char
  = '"' '"' { return '"'; }
  / [^"]

Pruébelo en http://jsfiddle.net/knvzk/10 o http://pegjs.majda.cz/online . Descargue el analizador generado en https://gist.github.com/3362830 .


2
¿CLAVIJA? No está construyendo un AST con poca memoria para una gramática tipo III. ¿Puede manejar campos que contienen caracteres de nueva línea porque ese es el caso más difícil de cubrir en un analizador de 'gramática regular'? De cualquier manera, +1 para un enfoque novedoso.
Evan Plaice

1
Sí, maneja la nueva línea dentro de un campo.
Trevor Dixon el

2
Bien ... Con eso solo, es mejor que el 95% de todas las implementaciones que he visto. Si desea verificar el cumplimiento total de RFC, eche un vistazo a las pruebas aquí ( jquery-csv.googlecode.com/git/test/test.html ).
Evan Plaice el

66
Bien jugado. +1 por activarme a PEG. Me encantan los generadores de analizadores sintácticos. "¿Por qué programar a mano en cinco días lo que puede pasar cinco años de su vida automatizando?" - Terence Parr, ANTLR
Subfuzion

14

csvToArray v1.3

Una función compacta (645 bytes) pero compatible para convertir una cadena CSV en una matriz 2D, conforme al estándar RFC4180.

https://code.google.com/archive/p/csv-to-array/downloads

Uso común: jQuery

 $.ajax({
        url: "test.csv",
        dataType: 'text',
        cache: false
 }).done(function(csvAsString){
        csvAsArray=csvAsString.csvToArray();
 });

Uso común: Javascript

csvAsArray = csvAsString.csvToArray();

Anular separador de campo

csvAsArray = csvAsString.csvToArray("|");

Anular separador de registros

csvAsArray = csvAsString.csvToArray("", "#");

Anular Saltar encabezado

csvAsArray = csvAsString.csvToArray("", "", 1);

Anular todo

csvAsArray = csvAsString.csvToArray("|", "#", 1);

Esto suena interesante pero no puedo encontrar el código ahora. ¿Puedes publicarlo de nuevo?
Sam Watkins

1
He actualizado la publicación principal con un enlace actual. Muchas gracias.
dt192

3

No estoy seguro de por qué no pude kirtans ex. para trabajar para mi Parecía estar fallando en campos vacíos o tal vez campos con comas finales ...

Este parece manejar ambos.

No escribí el código del analizador, solo un contenedor alrededor de la función del analizador para que esto funcione para un archivo. ver atribución

    var Strings = {
        /**
         * Wrapped csv line parser
         * @param s string delimited csv string
         * @param sep separator override
         * @attribution : http://www.greywyvern.com/?post=258 (comments closed on blog :( )
         */
        parseCSV : function(s,sep) {
            // http://stackoverflow.com/questions/1155678/javascript-string-newline-character
            var universalNewline = /\r\n|\r|\n/g;
            var a = s.split(universalNewline);
            for(var i in a){
                for (var f = a[i].split(sep = sep || ","), x = f.length - 1, tl; x >= 0; x--) {
                    if (f[x].replace(/"\s+$/, '"').charAt(f[x].length - 1) == '"') {
                        if ((tl = f[x].replace(/^\s+"/, '"')).length > 1 && tl.charAt(0) == '"') {
                            f[x] = f[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"');
                          } else if (x) {
                        f.splice(x - 1, 2, [f[x - 1], f[x]].join(sep));
                      } else f = f.shift().split(sep).concat(f);
                    } else f[x].replace(/""/g, '"');
                  } a[i] = f;
        }
        return a;
        }
    }

1

Expresiones regulares al rescate! Estas pocas líneas de código manejan los campos correctamente entre comillas, comillas y nuevas líneas incrustadas basadas en el estándar RFC 4180.

function parseCsv(data, fieldSep, newLine) {
    fieldSep = fieldSep || ',';
    newLine = newLine || '\n';
    var nSep = '\x1D';
    var qSep = '\x1E';
    var cSep = '\x1F';
    var nSepRe = new RegExp(nSep, 'g');
    var qSepRe = new RegExp(qSep, 'g');
    var cSepRe = new RegExp(cSep, 'g');
    var fieldRe = new RegExp('(?<=(^|[' + fieldSep + '\\n]))"(|[\\s\\S]+?(?<![^"]"))"(?=($|[' + fieldSep + '\\n]))', 'g');
    var grid = [];
    data.replace(/\r/g, '').replace(/\n+$/, '').replace(fieldRe, function(match, p1, p2) {
        return p2.replace(/\n/g, nSep).replace(/""/g, qSep).replace(/,/g, cSep);
    }).split(/\n/).forEach(function(line) {
        var row = line.split(fieldSep).map(function(cell) {
            return cell.replace(nSepRe, newLine).replace(qSepRe, '"').replace(cSepRe, ',');
        });
        grid.push(row);
    });
    return grid;
}

const csv = 'A1,B1,C1\n"A ""2""","B, 2","C\n2"';
const separator = ',';      // field separator, default: ','
const newline = ' <br /> '; // newline representation in case a field contains newlines, default: '\n' 
var grid = parseCsv(csv, separator, newline);
// expected: [ [ 'A1', 'B1', 'C1' ], [ 'A "2"', 'B, 2', 'C <br /> 2' ] ]

No necesita un generador de analizadores como lex / yacc. La expresión regular maneja RFC 4180 correctamente gracias a la mirada hacia atrás positiva, hacia atrás negativa y hacia adelante positiva.

Clonar / descargar código en https://github.com/peterthoeny/parse-csv-js


Las expresiones regulares se implementan utilizando máquinas de estados finitos, por lo que, de hecho, necesita FSM.
Henry Henrinson

@HenryHenrinson: No necesariamente. Te reto a que encuentres un problema con el código anterior. Lo uso en producción. También es posible hacer un análisis más complejo con expresiones regulares. No necesita un analizador LL para crear un árbol de sintaxis. Aquí hay un blog: Cómo usar expresiones regulares para analizar
Peter Thoeny

@HenryHenrinson: Oh, sí, tonto, estamos de acuerdo violento :-)
Peter Thoeny

-1

He construido este script javascript para analizar un CSV en cadena para agrupar el objeto. Me parece mejor dividir todo el CSV en líneas, campos y procesarlos en consecuencia. Creo que le facilitará cambiar el código para satisfacer sus necesidades.

Espero que te ayude. Gracias.

    //
    //
    // CSV to object
    //
    //

    const new_line_char = '\n';
    const field_separator_char = ',';

    function parse_csv(csv_str) {

        var result = [];

        let line_end_index_moved = false;
        let line_start_index = 0;
        let line_end_index = 0;
        let csr_index = 0;
        let cursor_val = csv_str[csr_index];
        let found_new_line_char = get_new_line_char(csv_str);
        let in_quote = false;

        // handle \r\n
        if (found_new_line_char == '\r\n') {
            csv_str = csv_str.split(found_new_line_char).join(new_line_char);
        }
        // handle last char is not \n
        if (csv_str[csv_str.length - 1] !== new_line_char) {
            csv_str += new_line_char;
        }

        while (csr_index < csv_str.length) {
            if (cursor_val === '"') {
                in_quote = !in_quote;
            } else if (cursor_val === new_line_char) {
                if (in_quote === false) {
                    if (line_end_index_moved && (line_start_index <= line_end_index)) {
                        result.push(parse_csv_line(csv_str.substring(line_start_index, line_end_index)));
                        line_start_index = csr_index + 1;
                    } // else: just ignore line_end_index has not moved or line has not been sliced for parsing the line
                } // else: just ignore because we are in quote
            }
            csr_index++;
            cursor_val = csv_str[csr_index];
            line_end_index = csr_index;
            line_end_index_moved = true;
        }

        // handle \r\n
        if (found_new_line_char == '\r\n') {
            let new_result = [];
            let curr_row;
            for (var i = 0; i < result.length; i++) {
                curr_row = [];
                for (var j = 0; j < result[i].length; j++) {
                    curr_row.push(result[i][j].split(new_line_char).join('\r\n'));
                }
                new_result.push(curr_row);
            }
            result = new_result;
        }

        return result;
    }

    function parse_csv_line(csv_line_str) {

        var result = [];

        // let field_end_index_moved = false;
        let field_start_index = 0;
        let field_end_index = 0;
        let csr_index = 0;
        let cursor_val = csv_line_str[csr_index];
        let in_quote = false;

        // Pretend that the last char is the separator_char to complete the loop
        csv_line_str += field_separator_char;

        while (csr_index < csv_line_str.length) {
            if (cursor_val === '"') {
                in_quote = !in_quote;
            } else if (cursor_val === field_separator_char) {
                if (in_quote === false) {
                    if (field_start_index <= field_end_index) {
                        result.push(parse_csv_field(csv_line_str.substring(field_start_index, field_end_index)));
                        field_start_index = csr_index + 1;
                    } // else: just ignore field_end_index has not moved or field has not been sliced for parsing the field
                } // else: just ignore because we are in quote
            }
            csr_index++;
            cursor_val = csv_line_str[csr_index];
            field_end_index = csr_index;
            field_end_index_moved = true;
        }

        return result;
    }

    function parse_csv_field(csv_field_str) {
        with_quote = (csv_field_str[0] === '"');

        if (with_quote) {
            csv_field_str = csv_field_str.substring(1, csv_field_str.length - 1); // remove the start and end quotes
            csv_field_str = csv_field_str.split('""').join('"'); // handle double quotes
        }

        return csv_field_str;
    }

    // initial method: check the first newline character only
    function get_new_line_char(csv_str) {
        if (csv_str.indexOf('\r\n') > -1) {
            return '\r\n';
        } else {
            return '\n'
        }
    }

-3

¿Por qué no simplemente usar .split (',')?

http://www.w3schools.com/jsref/jsref_split.asp

var str="How are you doing today?";
var n=str.split(" "); 

2
¿Por qué es esta una mala respuesta? Es nativo, coloca el contenido de la cadena en una matriz factible ...
Micah

20
Muchas razones Primero, no elimina las comillas dobles en valores delimitados. No maneja la división de línea. No escapa a las comillas dobles-dobles utilizadas para escapar de las comillas dobles utilizadas en valores delimitados. No permite valores vacíos. etc, etc ... La flexibilidad del formato CSV hace que sea muy fácil de usar pero difícil de analizar. No rechazaré esto, pero solo porque no rechazo las respuestas de la competencia.
Evan Plaice

1
¿Qué pasa cuando encuentras un valor que contiene un carácter de nueva línea? Una función de división simple lo interpretará incorrectamente como el final de una entrada en lugar de omitirla como debería. Analizar CSV es mucho más complicado que solo proporcionar 2 rutinas divididas (una para líneas nuevas, otra para delimitadores).
Evan Plaice

2
(cont) También dividido en valores nulos (a, null ,, value) no devuelve nada, mientras que debería devolver una cadena vacía. No me malinterpretes, dividir es un buen comienzo si estás 100% seguro de que los datos entrantes no romperán el analizador, pero crear un analizador robusto que pueda manejar cualquier dato que cumpla con RFC 4801 es significativamente más complicado.
Evan Plaice

8
Evan, creo que tu biblioteca de JavaScript es increíble. Pero aquí hay otra perspectiva: aprecié esta respuesta, ya que simplemente estoy almacenando una serie de números de una manera muy predecible. Para mí es mucho más importante garantizar la compatibilidad y el mantenimiento de JavaScript entre navegadores lo más lejos posible en el futuro, que incluir una biblioteca grande (aunque bien escrita y probada). Diferentes necesidades requieren diferentes enfoques. Si alguna vez necesito energía CSV real, ¡definitivamente me comprometeré a usar su biblioteca! :-)
moodboom
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.