Anchor tag download attribute not working :Bug in Chrome 35.0.1916.114
Asked Answered
C

6

30

I am trying to refer to this code where a we are downloading a CSV file on click of a link.

$(document).ready(function () {

    function exportTableToCSV($table, filename) {

        var $rows = $table.find('tr:has(td)'),

            // Temporary delimiter characters unlikely to be typed by keyboard
            // This is to avoid accidentally splitting the actual contents
            tmpColDelim = String.fromCharCode(11), // vertical tab character
            tmpRowDelim = String.fromCharCode(0), // null character

            // actual delimiter characters for CSV format
            colDelim = '","',
            rowDelim = '"\r\n"',

            // Grab text from table into CSV formatted string
            csv = '"' + $rows.map(function (i, row) {
                var $row = $(row),
                    $cols = $row.find('td');

                return $cols.map(function (j, col) {
                    var $col = $(col),
                        text = $col.text();

                    return text.replace('"', '""'); // escape double quotes

                }).get().join(tmpColDelim);

            }).get().join(tmpRowDelim)
                .split(tmpRowDelim).join(rowDelim)
                .split(tmpColDelim).join(colDelim) + '"',

            // Data URI
            csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

        $(this)
            .attr({
            'download': filename,
                'href': csvData,
                'target': '_blank'
        });
    }

    // This must be a hyperlink
    $(".export").on('click', function (event) {
        // CSV
        exportTableToCSV.apply(this, [$('#dvData>table'), 'export.csv']);

        // IF CSV, don't do event.preventDefault() or return false
        // We actually need this to be a typical hyperlink
    });
});

But somehow, the downloaded file is named as download without extension in Chrome v35.0.1916.114 , one workaround was to change data:application/csv to data:text/csv, but that only helped in getting the extension correct in the downloaded file i.e. it now downloads as download.csv.

The issue with the download attribute still remains. I wanted to name my file as export.csv, but it still gives me download.csv.

Collaborate answered 22/5, 2014 at 19:57 Comment(7)
I was running Chrome 34. Downloaded as "export.csv", upgraded to 35 downloaded as "download". Seems like a chrome bug to me.Concinnate
Yes... so is there any workaround for this?Collaborate
Just file a bug and wait for a fix to be released (I'm running into this same issue). It will probably be very soon. If you can't wait you'll have to send the csv down to the server with an ajax request so you can serve it back up.Loathly
So can i use nodejs http proxy server and get it from there? if so can someone give me any pointers how to do it?Collaborate
#13912698 seems to work see jsFiddle: jsfiddle.net/pnMH2Concinnate
I confirm this happens here too, only "download" without extension downloads, should be "export.csv" any quick fix on this or Google news about it ?Continent
This bug has been fixed in Chrome 36, released July 16, 2014. Your JSFiddle now works again!Gerald
C
29

So you should change this:

// Data URI
csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

$(this)
    .attr({
    'download': filename,
        'href': csvData,
        'target': '_blank'
});

To This

// Data URI
//csvData = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv), //old way
blob = new Blob([csv], { type: 'text/csv' }); //new way
var csvUrl = URL.createObjectURL(blob);

$(this)
.attr({
    'download': filename,
    'href': csvUrl
});

And it should work!

Crean answered 30/5, 2014 at 14:11 Comment(5)
right, blob still works with download attribute correctly. here is a demo: html5-demos.appspot.com/static/a.download.htmlThurber
This works great! Probably an even better solution than using dataAltruism
This should be the accepted solution imo. Works like a charm.Risner
I actually need 'target': '_blank' to make it work...Chrome 37Daman
@Mathew Thanks, you saved my day. I use var universalBOM = "\uFEFF"; //var uri = 'data:text/csv;charset=utf-8,' + encodeURIComponent(universalBOM + CSV); var blob = new Blob([universalBOM, CSV], {type: 'application/xls;charset=UTF-8', encoding:"UTF-8"}); //new way var csvUrl = URL.createObjectURL(blob);Perrone
S
9

This is a bug in Chrome 35 reported in issue #377860.

Update: This bug was merged into issue #373182. You can click the star to tell the devs you think this issue should get fixed and also get notified of changes.

Typically the chromium team releases an update every 2 weeks so you can expect a fix soon since this is marked as Pri-1 which I assume means highest priority.

Scansion answered 27/5, 2014 at 21:46 Comment(3)
Looks like it's fixed as of June 20th, 2014.Hornswoggle
I don't think it's fixed, I'm still having this issue.Corrupt
I just started having this issue after switching an old version of jquery to the latest. Anyone know why?Mckeown
P
2

For me worked:

var content = "some content";
var link = document.createElement('a');
var blob = new Blob(["\ufeff", content]);
var url = URL.createObjectURL(blob);
link.href = url;
link.setAttribute('download', 'file.csv');
link.click();
Pagandom answered 29/5, 2014 at 8:24 Comment(1)
This is not working in iOS. If i want to make it work in iOS, then how can i make it?Agosto
P
1

Here is a bit that worked for me (in Chrome and Firefox). I'm building a xls file out of a table.

  function downloadInnerHtml(filename,elId,mimeType){
    var elHtml='<table border="1">'+document.getElementById(elId).innerHTML+'</table>';
    var link=document.createElement('a');
    mimeType=mimeType || 'application/xls';

    var blob=new Blob([elHtml],{type:mimeType});
    var url=URL.createObjectURL(blob);
    link.href=url;

    link.setAttribute('download', filename);
    link.innerHTML = "Export to CSV";
    document.body.appendChild(link);
    link.click();
  }

  $(document).on("click","#exportButton",function(){
    var date=new Date();
    var mm=date.getMonth()+1;
    var dd=date.getDate();
    var yy=date.getFullYear();
    var timeStamp=yy+""+((mm<10)?"0"+mm:mm)+""+((dd<10)?"0"+dd:dd);
    var fileName=timeStamp+'_Employees.xls';
    downloadInnerHtml(fileName,'mainEmployeeTable','application/xls');
  });

Hope that helps someone else...

--Charles

Portland answered 28/5, 2014 at 23:35 Comment(2)
why do we keep on getting pop-up: The file format and extension of download.xls don't match. ?Chuffy
Aakash, try changing that to text/csv. Since it looks like you were trying to pull a CSV instead of an XLS.Portland
C
0

When I tried this code, I was not able to get results in IE plus this code only iterates over td, it will skip any th present in your table. I have modified the code to resolve both the issues I was facing:

$(document).ready(function () {
    function exportTableToCSV($table, filename) {

            var $rows = $table.find('tr'),
            tmpColDelim = String.fromCharCode(11),
            tmpHeadDelim = String.fromCharCode(11),
            tmpRowDelim = String.fromCharCode(0),
            colDelim = '","',
            headDelim = '","',
            rowDelim = '"\r\n"',

            csv = '"' + $rows.map(function (i, row) {
                var $row = $(row),
                $cols = $row.find('td');
                $heads = $row.find('th');

                var c = $heads.map(function (k, head) {
                    var $head = $(head),
                    text = $head.text();
                    return text.replace(/"/g, '""');
                }).get().join(tmpHeadDelim);

                var d = $cols.map(function (j, col) {
                    var $col = $(col),
                    text = $col.text();
                    return text.replace(/"/g, '""');
                }).get().join(tmpColDelim);

            return (c+d);

        }).get().join(tmpRowDelim)
            .split(tmpRowDelim).join(rowDelim)
            .split(tmpHeadDelim).join(headDelim)
            .split(tmpColDelim).join(colDelim) + '"';


        var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE ");

        // if Internet Explorer (10+)
        if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
            var blob = new Blob([decodeURIComponent(csv)], {
                    type: 'text/csv;charset=utf8'
            });
            window.navigator.msSaveBlob(blob, filename);
        }
        else {
            var link = document.createElement('a');
            var blob = new Blob([csv],{type:'text/csv;charset=utf8'});
            var url = URL.createObjectURL(blob);
            link.href = url;
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();
        }
    }

    $("#fnExcelReport").on('click', function (event) {
        var args = [$('#tableContent'), 'Report.csv'];
        exportTableToCSV.apply(this, args);
    });
});

CodePen

Chuffy answered 8/11, 2017 at 12:42 Comment(0)
B
-1

append anchor tag using string add tag information in string and then append, it works for me for google chrome

Barnaba answered 14/2, 2015 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.