Search code examples
javascriptjsonexport-to-csv

Json to CSV convert Filename is invalid


I have written javascript code to convert json to csv file to download. Every file is perfectly getting converted and downloaded with the correct file names except one file has a problem regarding filename issue. On Chrome, other files are being downloaded with naming convention like abc_def_ghi.csv, but that only file is being downloaded with "download" file name without csv extension. However when you "Open With" Notepad, it shows the correct csv data. I am not sure what is the problem with it. The same problem is on Firefox except it sets some filename which is not according to convention and also sets extension, but everytime the file name is changed for same csv.

Here is the screen shot of Firefox when it asks for "save"

enter image description here

and here is the filenames of the same csv file downloaded twice.

enter image description here

and here is the screenshot of file downloaded from chrome.

enter image description here

And here is the code which I had written to convert json to csv and download.

function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {
                //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
                var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;

                var CSV = '';
                //Set Report title in first row or line

                //CSV += ReportTitle + '\r\n\n';

                //This condition will generate the Label/Header
                if (ShowLabel) {
                    var row = "";

                    //This loop will extract the label from 1st index of on array
                    for (var index in arrData[0]) {

                        //Now convert each value to string and comma-seprated
                        row += index + ',';
                    }

                    row = row.slice(0, -1);

                    //append Label row with line break
                    CSV += row + '\r\n';
                }

                //1st loop is to extract each row
                for (var i = 0; i < arrData.length; i++) {
                    var row = "";

                    //2nd loop will extract each column and convert it in string comma-seprated
                    for (var index in arrData[i]) {
                        row += '"' + arrData[i][index] + '",';
                    }

                    row.slice(0, row.length - 1);

                    //add a line break after each row
                    CSV += row + '\r\n';
                }

                if (CSV == '') {
                    alert("Invalid data");
                    return;
                }

                //Generate a file name
                var fileName = "";
                //this will remove the blank-spaces from the title and replace it with an underscore
                fileName += ReportTitle.replace(/ /g, "_");

                //Check for ie
                var ie = getInternetExplorerVersion();
                if (ie == -1) {
                    //Initialize file format you want csv or xls
                    var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);

                    // Now the little tricky part.
                    // you can use either>> window.open(uri);
                    // but this will not work in some browsers
                    // or you will not get the correct file extension    

                    //this trick will generate a temp <a /> tag
                    var link = document.createElement("a");
                    link.href = uri;

                    //set the visibility hidden so it will not effect on your web-layout
                    link.style.visibility = "hidden";
                    link.download = fileName + ".csv";

                    //this part will append the anchor tag and remove it after automatic click
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                } else {
                    var blob = new Blob([CSV], { type: "text/csv;charset=utf-8;" });
                    navigator.msSaveBlob(blob, fileName + ".csv")
                }
            }

Solution

  • Thankfully after days of struggling, I have resolved the issue. I was really panic to find the cause of filename issue. Thanks to my teammate, who revealed after I was getting disappointed that the issue is being caused by Google Analytics. Since we were facing this issue only on Production, and not on localhost or dev testing site and the Google Analytics code have a condition for Production, so the Google Analytics was being ignored on localhost and Dev testing environment.

    There were suggestions to use encodeURI or encodeURIComponent instead of escape to encode the csv string and I applied them because it seemed to me that this is a csv string encoding issue. However in the end what worked for me is given below

    link.target = "_blank";
    

    It was so simple and small but logical which I did not notice that I have not it in the code and found it in someone's else post on JSON to CSV convert code.

    Hopefully this will be helpful for any developer facing filename issue due to "Google Analytics"