如何将文件名和文件扩展名添加到 window.open 方法,该方法将 JSON 数组导出到 CSV 字符串然后导出到 javascript 中的文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19864061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 17:04:09  来源:igfitidea点击:

How to add filename and file extension to window.open method that exports a JSON array to a CSV string then to a file in javascript?

javascriptjsonexcelfilecsv

提问by jordan

I have the following code, which was found on the following question: https://stackoverflow.com/a/4130939/1055971

我有以下代码,可在以下问题中找到:https: //stackoverflow.com/a/4130939/1055971

function DownloadJSON2CSV(objArray)
{
    var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;

    var str = '';

    for (var i = 0; i < array.length; i++) {
        var line = '';

        for (var index in array[i]) {
            line += array[i][index] + ',';
        }

        line.slice(0,line.Length-1); 

        str += line + '\r\n';
    }

    window.open( "data:text/csv;charset=utf-8," + escape(str))

}

This code works very well. It downloads the file and saves it, but the issue is there is not a way to add a custom title to the file, and also, the file saves with no extension. For example, when the save function is called, the file name is 'download' by default with no file extension.When i add an extension through the windows file system (like .csv) and open the file again, all data is perfectly preserved.
I am hoping to figure out a way to preset the file name and file type before the download takes place. Any ideas?

这段代码工作得很好。它下载文件并保存它,但问题是没有办法为文件添加自定义标题,而且文件保存时没有扩展名。 例如,当调用 save 函数时,文件名默认为“下载”,没有文件扩展名。当我通过 Windows 文件系统(如 .csv)添加扩展名并再次打开文件时,所有数据都被完美保留。
我希望在下载之前找到一种预设文件名和文件类型的方法。有任何想法吗?

回答by Reza Nabati

create invisible link element( anchor tag) and initialize downloadproperty of aelement with desired file name and append in new created window and open and call programmatically click event on created aelement.

创建隐形链接元素(锚标记)和初始化下载的财产一个在新创建的窗口,创造开放和呼叫程序单击事件所需的文件名,并追加元素一个元素。

$(document).ready(function(){
    $('button').click(function(){
        var data = $('#txt').val();
        if(data == '')
            return;
        
        JSONToCSVConvertor(data, "Sample Report", true);
    });
});

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 = "MyReport_";
    //this will remove the blank-spaces from the title and replace it with an underscore
    fileName += ReportTitle.replace(/ /g,"_");   
    
    //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);
}
.txtarea{
    max-width:100%;
    min-height:200px;    
    display:block;
    width:100%;
}

.mydiv{
    padding:10px;
}

.gen_btn{
    padding:5px;
    background-color:#743ED9;
    color:white;
    font-family:arial;
    font-size:13px;
    border:2px solid black;
}

.gen_btn:hover{
    background-color:#9a64ff;
}
<div class='mydiv'>    
    <textarea id="txt" class='txtarea'>[{"Vehicle":"BMW","Date":"30, Jul 2013 09:24 AM","Location":"Hauz Khas, Enclave, New Delhi, Delhi, India","Speed":42},{"Vehicle":"Honda CBR","Date":"30, Jul 2013 12:00 AM","Location":"Military Road,  West Bengal 734013,  India","Speed":0},{"Vehicle":"Supra","Date":"30, Jul 2013 07:53 AM","Location":"Sec-45, St. Angel's School, Gurgaon, Haryana, India","Speed":58},{"Vehicle":"Land Cruiser","Date":"30, Jul 2013 09:35 AM","Location":"DLF Phase I, Marble Market, Gurgaon, Haryana, India","Speed":83},{"Vehicle":"Suzuki Swift","Date":"30, Jul 2013 12:02 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Civic","Date":"30, Jul 2013 12:00 AM","Location":"Behind Central Bank RO, Ram Krishna Rd by-lane, Siliguri, West Bengal, India","Speed":0},{"Vehicle":"Honda Accord","Date":"30, Jul 2013 11:05 AM","Location":"DLF Phase IV, Super Mart 1, Gurgaon, Haryana, India","Speed":71}]</textarea>
    <button class='gen_btn'>Generate File</button>
</div>

回答by megawac

//taken from https://stackoverflow.com/questions/283956/is-there-any-way-to-specify-a-suggested-filename-when-using-data-uri#15832569
function downloadWithName(uri, name) {
    function eventFire(el, etype){
        if (el.fireEvent) {
            (el.fireEvent('on' + etype));
        } else {
            var evObj = document.createEvent('Events');
            evObj.initEvent(etype, true, false);
            el.dispatchEvent(evObj);
        }
    }

    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    eventFire(link, "click");
}

downloadWithName("data:text/csv;charset=utf-8," + escape(str), "file.csv"); //didnt work when I tested in ff25

There appears to not be a good way to guarantee the behaviour cross browser

似乎没有一个很好的方法来保证跨浏览器的行为