Javascript: Download data to file from content within the page
setting is the following: I have a homepage where I display a diagram that has been cons开发者_如何转开发tructed using comma seperated values from within the page. I'd like to give users the possibility to download the data as cvs-file without contacting the server again. (as the data is already there) Is this somehow possible? I'd prefer a pure JavaScript solution.
So far I've discovered: http://pixelgraphics.us/downloadify/test.html but it involves flash which I'd like to avoid.
I can't imagine this question hasn't been asked before. I'm sorry to double post, but it seems I've used the wrong keywords or something - I haven't found a solution in these forums.
Tested on 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>
Simple solution :
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();
}
Usage
download("csv_data_here", "filename.csv", "text/csv");
Update:
Time certainly changes things ;-) When I first answered this question IE8 was the latest IE browser available (Nov 2010) and thus there was no cross browser way to accomplish this without a round trip to the server, or using a tool requiring Flash.
@Zectburno's answer will get you what you need now, however for historical context be aware of which IE browsers support which feature.
- btoa() is undefined in IE8 and IE9
- Blob is available in IE10+
Be sure to test in the browsers you need to support. Even though the Blob example in the other answer should work in IE10+ it doesn't work for me just clicking the link (browser does nothing, no error)... only if I right click and save target as "file.csv" then navigate to the file and double-click it can I open the file.
Test both approaches (btoa/Blob) in this JSFiddle. (here's the code)
<!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>
Original Answer:
I don't think there is an option available for this.
I would just adjust your code such that if Flash 10+ is detected (93% saturation as of September 2009) on the user's system, provide the Downloadify option, otherwise fallback to a server-side request.
As far as I know, this is not possible: This is why Downloadify was created.
You could try linking to a data:URL
containing CSV data, but there will be cross-browser trouble.
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;
}
I found this code elsewhere, here, previously
If your users have up to date browsers, the new Blob object could help you.
Based on the example here https://developer.mozilla.org/en/docs/DOM/Blob ("Blob constructor example usage"), you could do something like the following:
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";
HTML:
<a href="javascript:onDownload();">Download</a>
JavaScript:
function onDownload() {
document.location = 'data:Application/octet-stream,' +
encodeURIComponent(dataToDownload);
}
Taken from How to Download Data as a File From JavaScript
The most comprehensive solution I have run across is using FileSaver.js, handling many potential cross-browser issues for you with fallbacks.
It takes advantage of the Blob
object as other posters have done, and the creator even creates a Blob.js polyfill in case you need to support browser versions that don't support Blob
精彩评论