vue data convert charset array javascript csv dojo export client-side

data - ¿Cómo exportar información de matriz de JavaScript a csv(en el lado del cliente)?



js export csv (22)

Una función de flecha con ES6:

const dataToCsvURI = (data) => encodeURI( `data:text/csv;charset=utf-8,${data.map((row, index) => row.join('','')).join(`/n`)}` );

Entonces :

window.open( dataToCsvURI( [["name1", "city_name1"/*, ...*/], ["name2", "city_name2"/*, ...*/]] ) );

En caso de que alguien necesite esto para reactjs , react-csv está ahí para eso.

Sé que hay muchas preguntas de esta naturaleza pero necesito hacer esto usando JavaScript. Estoy usando Dojo 1.8 y tengo toda la información de los atributos en la matriz, que se ve así:

[["name1", "city_name1", ...]["name2", "city_name2", ...]]

¿Alguna idea de cómo puedo exportar esto a CSV en el lado del cliente?


Agregué a la función Xavier Johns para incluir también los encabezados de campo si es necesario, aunque usa jQuery. El bit $ .each tendrá que cambiarse para un bucle javascript nativo

function exportToCsv(filename, rows, headers = false) { var processRow = function (row) { row = $.map(row, function(value, index) { return [value]; }); var finalVal = ''''; for (var j = 0; j < row.length; j++) { if(i == 0 && j == 0 && headers == true){ var ii = 0; $.each(rows[i], function( index, value ) { //console.log(index); var fieldName = index === null ? '''' : index.toString(); //console.log(fieldName); var fieldResult = fieldName.replace(/"/g, ''""''); //console.log(fieldResult); if (fieldResult.search(/("|,|/n)/g) >= 0){ fieldResult = ''"'' + fieldResult + ''"''; } //console.log(fieldResult); if (ii > 0){ finalVal += '',''; finalVal += fieldResult; }else{ finalVal += fieldResult; } ii++; //console.log(finalVal); }); finalVal += ''/n''; //console.log(''end: ''+finalVal); } var innerValue = row[j] === null ? '''' : row[j].toString(); if (row[j] instanceof Date) { innerValue = row[j].toLocaleString(); }; var result = innerValue.replace(/"/g, ''""''); if (result.search(/("|,|/n)/g) >= 0){ result = ''"'' + result + ''"''; } if (j > 0){ finalVal += '',''; finalVal += result; }else{ finalVal += result; } } return finalVal + ''/n''; }; var csvFile = ''''; for (var i = 0; i < rows.length; i++) { csvFile += processRow(rows[i]); } var blob = new Blob([csvFile], { type: ''text/csv;charset=utf-8;'' }); if (navigator.msSaveBlob) { // IE 10+ navigator.msSaveBlob(blob, filename); }else{ var link = document.createElement("a"); if (link.download !== undefined) { // feature detection // Browsers that support HTML5 download attribute var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", filename); link.style.visibility = ''hidden''; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } }


Aquí hay una versión amigable de Angular:

constructor(private location: Location, private renderer: Renderer2) {} download(content, fileName, mimeType) { const a = this.renderer.createElement(''a''); mimeType = mimeType || ''application/octet-stream''; if (navigator.msSaveBlob) { navigator.msSaveBlob(new Blob([content], { type: mimeType }), fileName); } else if (URL && ''download'' in a) { const id = GetUniqueID(); this.renderer.setAttribute(a, ''id'', id); this.renderer.setAttribute(a, ''href'', URL.createObjectURL(new Blob([content], { type: mimeType }))); this.renderer.setAttribute(a, ''download'', fileName); this.renderer.appendChild(document.body, a); const anchor = this.renderer.selectRootElement(`#${id}`); anchor.click(); this.renderer.removeChild(document.body, a); } else { this.location.go(`data:application/octet-stream,${encodeURIComponent(content)}`); } };


Así es como descargo archivos CSV en el lado del cliente en mi aplicación Java GWT. Un agradecimiento especial a Xavier John por su solución. Se ha verificado que funciona en FF 24.6.0, IE 11.0.20 y Chrome 45.0.2454.99 (64 bits). Espero que esto le ahorre un poco de tiempo a alguien:

public class ExportFile { private static final String CRLF = "/r/n"; public static void exportAsCsv(String filename, List<List<String>> data) { StringBuilder sb = new StringBuilder(); for(List<String> row : data) { for(int i=0; i<row.size(); i++) { if(i>0) sb.append(","); sb.append(row.get(i)); } sb.append(CRLF); } generateCsv(filename, sb.toString()); } private static native void generateCsv(String filename, String text) /*-{ var blob = new Blob([text], { type: ''text/csv;charset=utf-8;'' }); if (navigator.msSaveBlob) // IE 10+ { navigator.msSaveBlob(blob, filename); } else { var link = document.createElement("a"); if (link.download !== undefined) // feature detection { // Browsers that support HTML5 download attribute var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", filename); link.style.visibility = ''hidden''; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } }-*/; }


Basándome en las respuestas anteriores, creé esta función que he probado en IE 11, Chrome 36 y Firefox 29

function exportToCsv(filename, rows) { var processRow = function (row) { var finalVal = ''''; for (var j = 0; j < row.length; j++) { var innerValue = row[j] === null ? '''' : row[j].toString(); if (row[j] instanceof Date) { innerValue = row[j].toLocaleString(); }; var result = innerValue.replace(/"/g, ''""''); if (result.search(/("|,|/n)/g) >= 0) result = ''"'' + result + ''"''; if (j > 0) finalVal += '',''; finalVal += result; } return finalVal + ''/n''; }; var csvFile = ''''; for (var i = 0; i < rows.length; i++) { csvFile += processRow(rows[i]); } var blob = new Blob([csvFile], { type: ''text/csv;charset=utf-8;'' }); if (navigator.msSaveBlob) { // IE 10+ navigator.msSaveBlob(blob, filename); } else { var link = document.createElement("a"); if (link.download !== undefined) { // feature detection // Browsers that support HTML5 download attribute var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", filename); link.style.visibility = ''hidden''; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } }

Por ejemplo: https://jsfiddle.net/jossef/m3rrLzk0/


Cree un blob con los datos csv .ie var blob = new Blob([data], type:"text/csv");

Si el navegador admite guardar blobs, es decir, if window.navigator.mSaveOrOpenBlob)===true , guarde los datos csv utilizando: window.navigator.msSaveBlob(blob, ''filename.csv'')

Si el navegador no admite guardar y abrir blobs, guarde los datos csv como:

var downloadLink = document.createElement(''<a></a>''); downloadLink.attr(''href'', window.URL.createObjectURL(blob)); downloadLink.attr(''download'', filename); downloadLink.attr(''target'', ''_blank''); document.body.append(downloadLink);

Fragmento de código completo:

var filename = ''data_''+(new Date()).getTime()+''.csv''; var charset = "utf-8"; var blob = new Blob([data], { type: "text/csv;charset="+ charset + ";" }); if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(blob, filename); } else { var downloadLink = document.element(''<a></a>''); downloadLink.attr(''href'', window.URL.createObjectURL(blob)); downloadLink.attr(''download'', filename); downloadLink.attr(''target'', ''_blank''); document.body.append(downloadLink); downloadLink[0].click(); }


En caso de que alguien necesite esto para knockout js, funciona bien con básicamente la solución propuesta:

html:

<a data-bind="attr: {download: filename, href: csvContent}">Download</a>

ver modelo:

// for the download link this.filename = ko.computed(function () { return ko.unwrap(this.id) + ''.csv''; }, this); this.csvContent = ko.computed(function () { if (!this.csvLink) { var data = ko.unwrap(this.data), ret = ''data:text/csv;charset=utf-8,''; ret += data.map(function (row) { return row.join('',''); }).join(''/n''); return encodeURI(ret); } }, this);


En la actualización de Chrome 35, se modificó el comportamiento del atributo de descarga.

https://code.google.com/p/chromium/issues/detail?id=373182

para trabajar esto en cromo, usa este

var pom = document.createElement(''a''); var csvContent=csv; //here we load our csv data var blob = new Blob([csvContent],{type: ''text/csv;charset=utf-8;''}); var url = URL.createObjectURL(blob); pom.href = url; pom.setAttribute(''download'', ''foo.csv''); pom.click();


Esta es una respuesta modificada basada en la respuesta aceptada en la que los datos provendrían de JSON.

JSON Data Ouptut: 0 :{emails: "SAMPLE Co., [email protected]"}, 1:{emails: "Another CO. , [email protected]"} JS: $.getJSON(''yourlink_goes_here'', { if_you_have_parameters}, function(data) { var csvContent = "data:text/csv;charset=utf-8,"; var dataString = ''''; $.each(data, function(k, v) { dataString += v.emails + "/n"; }); csvContent += dataString; var encodedUri = encodeURI(csvContent); var link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", "your_filename.csv"); document.body.appendChild(link); // Required for FF link.click(); });


Esta solución debería funcionar con Internet Explorer 10+, Edge, versiones anteriores y nuevas de Chrome, FireFox, Safari, ++

La respuesta aceptada no funcionará con IE y Safari.

// Example data given in question text var data = [ [''name1'', ''city1'', ''some other info''], [''name2'', ''city2'', ''more info''] ]; // Building the CSV from the Data two-dimensional array // Each column is separated by ";" and new line "/n" for next row var csvContent = ''''; data.forEach(function(infoArray, index) { dataString = infoArray.join('';''); csvContent += index < data.length ? dataString + ''/n'' : dataString; }); // The download function takes a CSV string, the filename and mimeType as parameters // Scroll/look down at the bottom of this snippet to see how download is called var download = function(content, fileName, mimeType) { var a = document.createElement(''a''); mimeType = mimeType || ''application/octet-stream''; if (navigator.msSaveBlob) { // IE10 navigator.msSaveBlob(new Blob([content], { type: mimeType }), fileName); } else if (URL && ''download'' in a) { //html5 A[download] a.href = URL.createObjectURL(new Blob([content], { type: mimeType })); a.setAttribute(''download'', fileName); document.body.appendChild(a); a.click(); document.body.removeChild(a); } else { location.href = ''data:application/octet-stream,'' + encodeURIComponent(content); // only this mime type is supported } } download(csvContent, ''dowload.csv'', ''text/csv;encoding:utf-8'');

Al ejecutar el fragmento de código se descargarán los datos simulados como csv

Créditos a dandavis https://.com/a/16377813/1350598


Hay dos preguntas aquí:

  1. Cómo convertir una matriz a la cadena csv
  2. Cómo guardar esa cadena en un archivo

Todas las respuestas a la primera pregunta (excepto la de Milimetric) aquí parecen una exageración. Y el de Milimetric no cubre los requisitos altrenativos, como rodear cadenas con comillas o convertir matrices de objetos.

Aquí están mis opiniones sobre esto:

Para un simple csv, un mapa () y una combinación () son suficientes:

var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]]; 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

Este método también le permite especificar un separador de columna distinto de una coma en la combinación interna. por ejemplo una pestaña: d.join(''/t'')

Por otro lado, si quieres hacerlo correctamente y encerrar cadenas entre comillas ", entonces puedes usar un poco de magia 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 tienes una matriz de objetos como:

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(Object.values(d)); }) .join(''/n'') .replace(/(^/[)|(/]$)/mg, '''');


Hay que ir

<!doctype html> <html> <head></head> <body> <a href=''#'' onclick=''downloadCSV({ filename: "stock-data.csv" });''>Download CSV</a> <script type="text/javascript"> var stockData = [ { Symbol: "AAPL", Company: "Apple Inc.", Price: "132.54" }, { Symbol: "INTC", Company: "Intel Corporation", Price: "33.45" }, { Symbol: "GOOG", Company: "Google Inc", Price: "554.52" }, ]; function convertArrayOfObjectsToCSV(args) { var result, ctr, keys, columnDelimiter, lineDelimiter, data; data = args.data || null; if (data == null || !data.length) { return null; } columnDelimiter = args.columnDelimiter || '',''; lineDelimiter = args.lineDelimiter || ''/n''; keys = Object.keys(data[0]); result = ''''; result += keys.join(columnDelimiter); result += lineDelimiter; data.forEach(function(item) { ctr = 0; keys.forEach(function(key) { if (ctr > 0) result += columnDelimiter; result += item[key]; ctr++; }); result += lineDelimiter; }); return result; } window.downloadCSV = function(args) { var data, filename, link; var csv = convertArrayOfObjectsToCSV({ data: stockData }); if (csv == null) return; filename = args.filename || ''export.csv''; if (!csv.match(/^data:text//csv/i)) { csv = ''data:text/csv;charset=utf-8,'' + csv; } data = encodeURI(csv); link = document.createElement(''a''); link.setAttribute(''href'', data); link.setAttribute(''download'', filename); document.body.appendChild(link); link.click(); document.body.removeChild(link); } </script> </body> </html>


La solución de @Default funciona a la perfección en Chrome (¡muchas gracias por eso!) Pero tuve un problema con IE.

Aquí hay una solución (funciona en IE10):

var csvContent=data; //here we load our csv data var blob = new Blob([csvContent],{ type: "text/csv;charset=utf-8;" }); navigator.msSaveBlob(blob, "filename.csv")


Las respuestas anteriores funcionan, pero tenga en cuenta que si se abre en formato .xls, las columnas ~~ podrían estar separadas por ''/t'' lugar de '','' , la respuesta https://.com/a/14966131/6169225 funcionó bien para mí, siempre y cuando usé .join(''/t'') en los arreglos en lugar de .join('','') .


Puede usar el siguiente fragmento de código para exportar una matriz a un archivo CSV usando Javascript.

Esto maneja parte de caracteres especiales también

var arrayContent = [["Séjour 1, é,í,ú,ü,ű"],["Séjour 2, é,í,ú,ü,ű"]]; var csvContent = arrayContent.join("/n"); var link = window.document.createElement("a"); link.setAttribute("href", "data:text/csv;charset=utf-8,%EF%BB%BF" + encodeURI(csvContent)); link.setAttribute("download", "upload_data.csv"); link.click();

Here está el enlace para trabajar jsfiddle


Puedes hacer esto en JavaScript nativo. Tendrá que analizar sus datos en el formato CSV correcto como tal (asumiendo que está utilizando una matriz de matrices para sus datos como ha descrito en la pregunta):

const rows = [["name1", "city1", "some other info"], ["name2", "city2", "more info"]]; let csvContent = "data:text/csv;charset=utf-8,"; rows.forEach(function(rowArray){ let row = rowArray.join(","); csvContent += row + "/r/n"; });

Luego, puede usar las funciones window.open y encodeURI JavaScript para descargar el archivo CSV de la siguiente manera:

var encodedUri = encodeURI(csvContent); window.open(encodedUri);

Editar:

Si desea darle a su archivo un nombre específico, tiene que hacer las cosas de manera un poco diferente, ya que esto no es compatible con el acceso a un URI de datos utilizando el método window.open . Para lograr esto, puede crear un nodo <a> DOM oculto y configurar su atributo de download siguiente manera:

var encodedUri = encodeURI(csvContent); var link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", "my_data.csv"); document.body.appendChild(link); // Required for FF link.click(); // This will download the data file named "my_data.csv".


Recomendaría usar una biblioteca como PapaParse: https://github.com/mholt/PapaParse

La respuesta aceptada actualmente tiene varios problemas, incluyendo:

  • falla si los datos contienen una coma
  • falla si los datos contienen un salto de línea
  • (tipo de) falla si los datos contienen una comilla

Una gran cantidad de soluciones de rollo propio para convertir datos a CSV, pero casi todas tendrán varias advertencias en cuanto al tipo de datos que formatearán correctamente sin dejar de lado Excel o similares.

Por qué no usar algo probado: Papa Parse

Papa.unparse(data[, config])

Entonces simplemente combine esto con una de las soluciones de descarga locales aquí, por ejemplo. el de @ArneHB se ve bien.


Utilizo esta función para convertir una string[][] en un archivo csv. Cita una celda, si contiene un " , a , u otro espacio en blanco (excepto espacios en blanco):

/** * Takes an array of arrays and returns a `,` sparated csv file. * @param {string[][]} table * @returns {string} */ function toCSV(table) { return table .map(function(row) { return row .map(function(cell) { // We remove blanks and check if the column contains // other whitespace,`,` or `"`. // In that case, we need to quote the column. if (cell.replace(/ /g, '''').match(/[/s,"]/)) { return ''"'' + cell.replace(/"/g, ''""'') + ''"''; } return cell; }) .join('',''); }) .join(''/n''); // or ''/r/n'' for windows }

Nota : no funciona en Internet Explorer <11 a menos que el map esté rellenado.

Nota : Si las celdas contienen números, puede agregar cell=''''+cell antes if (cell.replace... para convertir los números en cadenas.

O puede escribirlo en una línea usando ES6:

t.map(r=>r.map(c=>c.replace(/ /g, '''').match(/[/s,"]/)?''"''+c.replace(/"/g,''""'')+''"'':c).join('','')).join(''/n'')


Vine aquí buscando un poco más de cumplimiento con RFC 4180 y no pude encontrar una implementación, así que hice una (posiblemente ineficiente) para mis propias necesidades. Pensé en compartirlo con todos.

var content = [[''1st title'', ''2nd title'', ''3rd title'', ''another title''], [''a a a'', ''bb/nb'', ''cc,c'', ''dd"d''], [''www'', ''xxx'', ''yyy'', ''zzz'']]; var finalVal = ''''; for (var i = 0; i < content.length; i++) { var value = content[i]; for (var j = 0; j < value.length; j++) { var innerValue = value[j]===null?'''':value[j].toString(); var result = innerValue.replace(/"/g, ''""''); if (result.search(/("|,|/n)/g) >= 0) result = ''"'' + result + ''"''; if (j > 0) finalVal += '',''; finalVal += result; } finalVal += ''/n''; } console.log(finalVal); var download = document.getElementById(''download''); download.setAttribute(''href'', ''data:text/csv;charset=utf-8,'' + encodeURIComponent(finalVal)); download.setAttribute(''download'', ''test.csv'');

Esperemos que esto ayude a alguien en el futuro. Esto combina tanto la codificación del CSV junto con la capacidad de descargar el archivo. En mi ejemplo en jsfiddle . Puede descargar el archivo (asumiendo el navegador HTML 5) o ver el resultado en la consola.

ACTUALIZAR:

Chrome ahora parece haber perdido la capacidad de nombrar el archivo. No estoy seguro de qué sucedió ni de cómo solucionarlo, pero siempre que uso este código (incluido el archivo jsfiddle), el archivo descargado ahora se llama download.csv .


Trabajando para todos los idiomas

function convertToCsv(fName, rows) { var csv = ''''; for (var i = 0; i < rows.length; i++) { var row = rows[i]; for (var j = 0; j < row.length; j++) { var val = row[j] === null ? '''' : row[j].toString(); val = val.replace(//t/gi, " "); if (j > 0) csv += ''/t''; csv += val; } csv += ''/n''; } // for UTF-16 var cCode, bArr = []; bArr.push(255, 254); for (var i = 0; i < csv.length; ++i) { cCode = csv.charCodeAt(i); bArr.push(cCode & 0xff); bArr.push(cCode / 256 >>> 0); } var blob = new Blob([new Uint8Array(bArr)], { type: ''text/csv;charset=UTF-16LE;'' }); if (navigator.msSaveBlob) { navigator.msSaveBlob(blob, fName); } else { var link = document.createElement("a"); if (link.download !== undefined) { var url = window.URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", fName); link.style.visibility = ''hidden''; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); } } } convertToCsv(''download.csv'', [ [''Order'', ''Language''], [''1'', ''English''], [''2'', ''Español''], [''3'', ''Français''], [''4'', ''Português''], [''5'', ''čeština''], [''6'', ''Slovenščina''], [''7'', ''Tiếng Việt''], [''8'', ''Türkçe''], [''9'', ''Norsk bokmål''], [''10'', ''Ελληνικά''], [''11'', ''беларускі''], [''12'', ''русский''], [''13'', ''Українська''], [''14'', ''հայերեն''], [''15'', ''עִברִית''], [''16'', ''اردو''], [''17'', ''नेपाली''], [''18'', ''हिंदी''], [''19'', ''ไทย''], [''20'', ''ქართული''], [''21'', ''中国''], [''22'', ''한국어''], [''23'', ''日本語''], ])


//It work in Chrome and IE ... I reviewed and readed a lot of answer. then i used it and tested in both ... var link = document.createElement("a"); if (link.download !== undefined) { // feature detection // Browsers that support HTML5 download attribute var blob = new Blob([CSV], { type: ''text/csv;charset=utf-8;'' }); var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", fileName); link.style = "visibility:hidden"; } if (navigator.msSaveBlob) { // IE 10+ link.addEventListener("click", function (event) { var blob = new Blob([CSV], { "type": "text/csv;charset=utf-8;" }); navigator.msSaveBlob(blob, fileName); }, false); } document.body.appendChild(link); link.click(); document.body.removeChild(link); //Regards