Microsoft

The Hoops Necessary To Download a CSV using jQuery AJAX

Okay so the first question some of you may have is why the Iced Cap made with Chocolate Milk. If you know me you already know this is my favorite beverage in the summer.  Now onto my article.
There are lots of articles on the methods and there are options but no article lists all the issues in one spot.
Step 1: Create your Ajax Call
I have provided sample code here. Replace .downloadCSV with your button name. Replace /ignitionapi/MyController/DownloadCSV
with your AJAX URL that will return the CSV in JSON format. Then change ‘download.csv’ to match the filename you want:

            jQuery(".downloadCSV").on('click', function (e) {
                jQuery.ajax({
                    type: "POST",
                    data: {},
                    url: '/ignitionapi/MyController/DownloadCSV',
                    dataType: 'json',
                    success: function (json) {
                        var csv = JSON.parse(json.replace(/"([\w]+)":/g, function ($0, $1) { return ('"' + $1.toLowerCase() + '":'); }));
                        downloadFile('download.csv', encodeURIComponent(csv));
                    }
                });
            });

Step 2: Coding the downloadFile function to download the CSV.
For Chrome and Firefox you can simply use the anchor with the download attribute and then click it.
As Internet Explorer does not currently support the Download attribute you will have to jump through a hoop. The solution for IE is to open a window, fill it with the CSV and then save it as the filename. We made the height and width 0 so it will hide behind save as. Hopefully IE will support this tag in future and we will not need this if.

            function downloadFile(fileName, csv) {
                if (navigator.userAgent.indexOf('MSIE') !== -1
                    || navigator.appVersion.indexOf('Trident/') > 0) {
                    var IEwindow = window.open("", "", "Width=0px; Height=0px");
                    IEwindow.document.write('sep=,\r\n' + csv);
                    IEwindow.document.close();
                    IEwindow.document.execCommand('SaveAs', true, fileName);
                    IEwindow.close();
                }
                else {
                    var aLink = document.createElement('a');
                    var evt = document.createEvent("MouseEvents");
                    evt.initMouseEvent("click", true, true, window,
                        0, 0, 0, 0, 0, false, false, false, false, 0, null);
                    aLink.download = fileName;
                    aLink.href = 'data:text/csv;charset=UTF-8,' + encodeURIComponent(csv);
                    aLink.dispatchEvent(evt);
                }
            }
            jQuery(".downloadCSV").on('click', function (e) {
                jQuery.ajax({
                    type: "POST",
                    data: {},
                    url: '/ignitionapi/Dashboard/DownloadCSV',
                    dataType: 'json',
                    success: function (json) {
                        var csv = JSON.parse(json.replace(/"([\w]+)":/g, function ($0, $1) { return ('"' + $1.toLowerCase() + '":'); }));
                        downloadFile('download.csv', encodeURIComponent(csv));
                    }
                });
            });

Step 3: Your Ajax Call
The key here is make it a public route and return a JsonResult. You get your CSV however you generate it then serialize it then return it. That’s it.
I always forget [PublicRoute].  See Corey Smith’s article for details why it is important.

        [PublicRoute]
        [HttpPost]
        public JsonResult DownloadCSV()
        {
            var csv = "This,is,your,csv,file\r\n1,2,3,4,5\r\n";
            var jsonCsv = JsonConvert.SerializeObject(csv,
                                    new JsonSerializerSettings());
            return Json(jsonCsv);
        }

Now you have it. On Chrome and Firefox it will download properly. On Internet Explorer it will briefly show the window that will be covered with save as. When saving it will save the proper file but the user will see a save as pop up. If someone has a better way to do the save as on IE I would love to hear.
 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Chris Williams

1 of 1 Sitecore Commerce MVPs in Canada.

More from this Author

Subscribe to the Weekly Blog Digest:

Sign Up
Categories
Follow Us
TwitterLinkedinFacebookYoutubeInstagram