Javascript: Download data to file from content within the page

54,928

Solution 1

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.

Solution 2

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>

Solution 3

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");

Solution 4

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.

Solution 5

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

Share:
54,928

Related videos on Youtube

Simon
Author by

Simon

Updated on July 09, 2022

Comments

  • Simon
    Simon almost 2 years

    setting is the following: I have a homepage where I display a diagram that has been constructed 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.

  • Ashraf Bashir
    Ashraf Bashir over 11 years
    expIFrame = window.framesexportiframe; //there's no framesexportiframe property in window !
  • Tomáš Zato
    Tomáš Zato about 10 years
    This is what I use, however in Mozzila Firefox, it causes horrible laggs for large files (>6MB).
  • Tomáš Zato
    Tomáš Zato about 10 years
    Can dowloadify be invoked from javascript? It would be tricky to create a flash button to fit my design.
  • scunliffe
    scunliffe about 10 years
    @TomášZato yes it can be invoked by JavaScript: github.com/dcneiner/Downloadify
  • Tomáš Zato
    Tomáš Zato about 10 years
    A don't see how's that an answer to my question. I've read the "documentation", however my question was if the download can be triggered from javascript. That's unfortunately impossible - the Downloadify button must be clicked.
  • DUzun
    DUzun over 9 years
    The click is required, but downloadify is not!
  • Bruno Finger
    Bruno Finger about 9 years
    This is a simple solution, but as mentioned on the original source, it is not known yet of a way to give the download file a name. If anyone knows the solution to this problem, it would be appreciated.
  • Nate Glenn
    Nate Glenn about 7 years
    If the URL is too big, then the download will simply fail in Chrome.
  • Zectbumo
    Zectbumo about 7 years
    It would be helpful to hear what you mean by "too big". How many MB are you trying to download? You might need to use the HTML 5 method since the older method can only handle ~4kB depending on browser.
  • Patrick Dougall
    Patrick Dougall about 7 years
    'application/octet-stream' was the key for me :+1:
  • swift-lynx
    swift-lynx about 4 years
    For large files, the problem is that the html parser needs to parse the entire string which takes time...