2010-11-15 13 views
18
configuración

es la siguiente: Tengo una página de inicio donde se muestra un diagrama que se ha construido utilizando valores separados por comas desde dentro de la página. Me gustaría dar a los usuarios la posibilidad de descargar los datos como archivo cvs sin tener que volver a contactar al servidor. (como los datos ya están allí) ¿Es esto de alguna manera posible? Prefiero una solución de JavaScript pura.Javascript: descargar datos al archivo del contenido dentro de la página

Hasta ahora he descubierto: http://pixelgraphics.us/downloadify/test.html pero se trata de flash que me gustaría evitar.

No me puedo imaginar que esta pregunta no se haya formulado antes. Lamento publicar dos veces, pero parece que he usado palabras clave incorrectas o algo así: no he encontrado una solución en estos foros.

Respuesta

5

actualización:

Tiempo sin duda cambia las cosas ;-) La primera vez que respondieron a esta pregunta IE8 fue la última versión del navegador IE disponible (nov 2010) y por lo tanto no había manera de navegadores de lograr esto sin un viaje redondo al servidor o utilizando una herramienta que requiera Flash.

@Zectburno's answer obtendrá lo que necesita ahora, sin embargo, para el contexto histórico, tenga en cuenta qué navegadores IE admiten qué característica.

  • btoa() está definido en IE8 e IE9
  • Blob está disponible en IE10 +

Asegúrese de probar en los navegadores que necesita para apoyar. Aunque el ejemplo de Blob en la otra respuesta debería funcionar en IE10 +, no funciona para mí simplemente haciendo clic en el enlace (el navegador no hace nada, no hay error) ... solo si hago clic derecho y guardo el objetivo como "file.csv", entonces vaya al archivo y haga doble clic en él. ¿Puedo abrir el archivo?

Test both approaches (btoa/Blob) in this JSFiddle. (aquí está el código)

<!doctype html> 
<html> 
<head> 
</head> 
<body> 
    <a id="a" target="_blank">Download CSV (via btoa)</a> 
    <script> 
    var csv = "a,b,c\n1,2,3\n"; 
    var a = document.getElementById("a"); 
    a.href = "data:text/csv;base64," + btoa(csv); 
    </script> 
    <hr/> 
    <a id="a2" download="Download.csv" type="text/csv">Download CSV (via Blob)</a> 
    <script> 
    var csv = "a,b,c\n1,2,3\n"; 
    var data = new Blob([csv]); 
    var a2 = document.getElementById("a2"); 
    a2.href = URL.createObjectURL(data); 
    </script> 
</body> 
</html> 

respuesta original:

No creo que hay una opción disponible para esto.

Me limitaría a ajustar su código de modo que si se detecta Flash 10+ (93% saturation as of September 2009) en el sistema del usuario, proporcione la opción Downloadify, de lo contrario recurrirá a una solicitud del lado del servidor.

+0

puede ser invocada dowloadify de javascript? Sería difícil crear un botón de flash para adaptarse a mi diseño. –

+0

@ TomášZato sí puede ser invocado por JavaScript: https://github.com/dcneiner/Downloadify – scunliffe

+0

A no veo cómo es esa una respuesta a mi pregunta. He leído la "documentación", sin embargo, mi pregunta era si la descarga se puede desencadenar desde JavaScript. Desafortunadamente [imposible] (https://github.com/dcneiner/Downloadify/issues/20) - se debe hacer clic en el botón Downloadify. –

3

Por lo que yo sé, esto no es posible: es por eso que se creó Downloadify.

Puede tratar de vincular a un data:URL que contenga datos CSV, pero habrá problemas entre navegadores.

3
function export(exportAs) { 
    var csvText = tableRowsToCSV(this.headTable.rows);­ 
    csvText += tableRowsToCSV(this.bodyTable.rows);­ 
    //open the iframe doc for writing 
    var expIFrame; 
    if (strBrowser == "MSIE") expIFrame = document.exportiframe; 
    else expIFrame = window.framesexportiframe; 
    var doc = expIFrame.document; 
    doc.open('text/plain', 'replace'); 
    doc.charset = "utf-8"; 
    doc.write(csvText); 
    doc.close(); 
    var fileName = exportAs + ".txt"; 
    doc.execCommand("SaveAs", null, fileName); 
} 

function tableRowsToCSV(theRows) { 
    var csv = ""; 
    var csvRow = ""; 
    var theCells; 
    var cellData = ""; 
    for (var r = 0; r < theRows.length; r++) { 
     theCells = theRows.item(r).cells; 
     for (var c = 0; c < theCells.length; c++) { 
      cellData = ""; 
      cellData = theCells.item(c).innerText; 
      if (cellData.indexOf(",") != -1) cellData = "'" + cellData + "'"; 
      if (cellData != "") csvRow += "," + cellData; 
     } 
     if (csvRow != "") csvRow = csvRow.substring(1, csvRow.length);­ 
     csv += csvRow + "\n"; 
     csvRow = ""; 
    } 
    return csv; 
} 

yo encontramos este código en otro lugar, here, previamente

+0

expIFrame = window.framesexportiframe; // ¡no hay propiedad framesexportiframe en la ventana! –

25

Probado en Safari 5, Firefox 6, Opera 12, Chrome 26.

<a id='a'>Download CSV</a> 
<script> 
    var csv = 'a,b,c\n1,2,3\n'; 
    var a = document.getElementById('a'); 
    a.href='data:text/csv;base64,' + btoa(csv); 
</script> 

HTML5

<a id='a' download='Download.csv' type='text/csv'>Download CSV</a> 
<script> 
    var csv = 'a,b,c\n1,2,3\n'; 
    var data = new Blob([csv]); 
    var a = document.getElementById('a'); 
    a.href = URL.createObjectURL(data); 
</script> 
+0

Esto es lo que uso, sin embargo, en Mozzila Firefox, causa laggs horribles para archivos grandes (> 6MB). –

+0

Si la URL es demasiado grande, la descarga simplemente fallará en Chrome. –

+0

Sería útil escuchar lo que quiere decir con "demasiado grande". ¿Cuántos MB estás tratando de descargar? Es posible que necesite usar el método HTML 5 ya que el método anterior solo puede manejar ~ 4kB dependiendo del navegador. – Zectbumo

2

Si los usuarios tienen hasta navegadores fecha, el nuevo objeto Blob podría ayudarle.

Basado en el ejemplo aquí https://developer.mozilla.org/en/docs/DOM/Blob ("blob constructor de ejemplo de uso"), que podría hacer algo como lo siguiente:

var typedArray = "123,abc,456"; //your csv as a string 
var blob = new Blob([typedArray], {type: "text/csv"}); 
var url = URL.createObjectURL(blob); 
var a = document.querySelector("#linktocsv"); // the id of the <a> element where you will render the download link 
a.href = url; 
a.download = "file.csv"; 
0

HTML:

<a href="javascript:onDownload();">Download</a> 

JavaScript:

function onDownload() { 
    document.location = 'data:Application/octet-stream,' + 
         encodeURIComponent(dataToDownload); 
} 

Tomado de How to Download Data as a File From JavaScript

+0

Esta es una solución simple, pero como se menciona en la fuente original, todavía no se conoce cómo dar un nombre al archivo de descarga. Si alguien conoce la solución a este problema, se lo agradecería. –

13

solución simple:

function download(content, filename, contentType) 
{ 
    if(!contentType) contentType = 'application/octet-stream'; 
     var a = document.createElement('a'); 
     var blob = new Blob([content], {'type':contentType}); 
     a.href = window.URL.createObjectURL(blob); 
     a.download = filename; 
     a.click(); 
} 

Uso

download("csv_data_here", "filename.csv", "text/csv"); 
+0

''application/octet-stream'' fue la clave para mí: +1: –

1

La solución más completa que he encontrado es el uso de FileSaver.js, el manejo de muchos posibles problemas de cross-browser para usted con retrocesos.

Se aprovecha del objeto Blob Como otros lo han hecho, y el creador incluso crea una Blob.js polyfill en caso de tener que soportar versiones de navegadores que no soportan Blob

Cuestiones relacionadas