簡體   English   中英

execCommand('SaveAs',true,'data.csv'); 在IE中無法正常工作

[英]execCommand('SaveAs', true, 'data.csv'); not working in IE

我正在將AngularJS與ng-grid一起使用。 用於ng-grid的CSV導出插件無法在IE上很好地使用,因此我們使用iframe構建了一種變通方法,以獲取csv數據並下載。 但是,即使將文件名后綴指定為.csv,exeCommand函數也僅保存為文本文件。 所有數據都在文本文件中,當轉換為csv時,它可以正常工作,但是我們需要從頭開始以.csv格式下載該文件。

我確實找到了可能是問題的根源的MS錯誤-好奇是否有人能想到解決方案: https : //support.microsoft.com/zh-cn/kb/929863

謝謝!

有問題的代碼:

function ngGridCsvExportPlugin (opts) {
    var self = this;
    self.grid = null;
    self.scope = null;
    self.init = function(scope, grid, services) {
        self.grid = grid;
        self.scope = scope;
        function showDs() {
            var keys = [];
            // setup our map index of `field`: `displayName`
            var keyNames = {};
            for (var f in grid.config.columnDefs) { keys.push(grid.config.columnDefs[f].field);}

            // build a map of field i.e. {metric_name: "Metric Name", age: "Age"}
            for (var f in grid.config.columnDefs) {
                keyNames[grid.config.columnDefs[f].field] = grid.config.columnDefs[f].displayName;
            }
            var getCsvFileForIE = function(target) {
                var csvData = target.attributes["data-csv"].value;
                if ( ! supportsDataUri() ) {
                    csvData = decodeURIComponent(csvData);

                    var iframe = document.getElementById('csvDownloadFrame');
                    iframe = iframe.contentWindow || iframe.contentDocument;

                    csvData = 'sep=,\r\n' + csvData;

                    iframe.document.open("text/html", "replace");
                    iframe.document.write(csvData);
                    iframe.document.close();
                    iframe.focus();
                    iframe.document.execCommand('SaveAs', true, 'data.csv');
                } else {
                    if (console && console.log) {
                        console.log('Trying to call getCsvFileForIE with non IE browser.');
                    }
                }
            };

            var supportsDataUri = function() {
                var isOldIE = navigator.appName === "Microsoft Internet Explorer";
                var isIE11 = !!navigator.userAgent.match(/Trident\/7\./);
                return ! (isOldIE || isIE11);  //Return true if not any IE
            };
            var csvData = '';
            function csvStringify(str) {
                if (str == null) { // we want to catch anything null-ish, hence just == not ===
                    return '';
                }
                if (typeof(str) === 'number') {
                    return '' + str;
                }
                if (typeof(str) === 'boolean') {
                    return (str ? 'TRUE' : 'FALSE') ;
                }
                if (typeof(str) === 'string') {
                    return str.replace(/"/g,'""');
                }

                return JSON.stringify(str).replace(/"/g,'""');
            }
            function swapLastCommaForNewline(str) {
                var newStr = str.substr(0,str.length - 1);
                return newStr + "\n";
            }
            for (var k in keys) {
                // unwrap our mapping dictionary
                csvData += '"' + csvStringify(keyNames[keys[k]]) + '",';
            }
            csvData = swapLastCommaForNewline(csvData);
            var gridData = grid.data;

            for (var gridRow in gridData) {
                for ( k in keys) {
                    var curCellRaw;
                    if (opts != null && opts.columnOverrides != null && opts.columnOverrides[keys[k]] != null) {
                        curCellRaw = opts.columnOverrides[keys[k]](gridData[gridRow][keys[k]]);
                    //dbogart added this to handle null cases
                    } else if (gridData[gridRow] === null) {
                        curCellRaw = '';
                    } else {
                        curCellRaw = gridData[gridRow][keys[k]];
                    }
                    csvData += '"' + csvStringify(curCellRaw) + '",';
                }
                csvData = swapLastCommaForNewline(csvData);
            }
            var fp = grid.$root.find(".ng-grid-buttons");
            var csvDataLinkPrevious = grid.$root.find('.ng-grid-buttons .csv-data-link-span');
            if (csvDataLinkPrevious != null) {csvDataLinkPrevious.remove() ; }
            var csvDataLinkHtml = "<div class='ngHeaderButton2'></div><span class=\"csv-data-link-span\">";
            //csvDataLinkHtml += "<a class ='exportLink' href=\"data:text/csv;charset=UTF-8,";
            //csvDataLinkHtml += encodeURIComponent(csvData);
            //csvDataLinkHtml += "\" download=\"Export.csv\"><i class='fa fa-file-excel-o excel-icon'></i></a></span>" ;
            csvDataLinkHtml += " <a ";
            if ( ! supportsDataUri()  ) {
                csvDataLinkHtml += " data-csv=\"";
                csvDataLinkHtml += encodeURIComponent(csvData);
                csvDataLinkHtml += "\" onclick='getCsvFileForIE(this);' >";
            } else {
                csvDataLinkHtml += "href=\"data:text/csv;charset=UTF-8,";
                csvDataLinkHtml += encodeURIComponent(csvData);
                csvDataLinkHtml += "\" download=\"Export.csv\">";
            }
            csvDataLinkHtml += "<i class='fa fa-file-excel-o excel-icon'></i></a></span>" ; //End csv-data-link-span

            //csvDataLinkHtml += "CSV Export</a> &nbsp;&nbsp;";

            //csvDataLinkHtml += "</br></span>"; //End csv-data-link-span
            fp.append(csvDataLinkHtml);
        }
        setTimeout(showDs, 0);
        scope.catHashKeys = function() {
            var hash = '';
            for (var idx in scope.renderedRows) {
                hash += scope.renderedRows[idx].$$hashKey;
            }
            return hash;
        };
        scope.$watch('catHashKeys()', showDs);
    };
}

function getCsvFileForIE(target) {
    var csvData = target.attributes["data-csv"].value;
    if ( ! supportsDataUri() ) {
        csvData = decodeURIComponent(csvData);

        var iframe = document.getElementById('csvDownloadFrame');
        iframe = iframe.contentWindow || iframe.contentDocument;

        csvData = 'sep=,\r\n' + csvData;

        iframe.document.open("text/html", "replace");
        iframe.document.write(csvData);
        iframe.document.close();
        iframe.focus();
        iframe.document.execCommand('SaveAs', true, 'data.csv');
    } else {
        if (console && console.log) {
            console.log('Trying to call getCsvFileForIE with non IE browser.');
        }
    }
};

function supportsDataUri() {
    var isOldIE = navigator.appName === "Microsoft Internet Explorer";
    var isIE11 = !!navigator.userAgent.match(/Trident\/7\./);
    return ! (isOldIE || isIE11);  //Return true if not any IE
};

這適用於Windows 7 IE 11上的我,請參閱https://stackoverflow.com/a/24417650/1198657

if (window.navigator.msSaveOrOpenBlob) {
  blobObject = new Blob([csvData]);
  window.navigator.msSaveOrOpenBlob(blobObject, 'Export.csv');
}

我實際上遇到了同樣的問題,但是在查看ui-grid的源代碼(在ui-grid.js文件中)之后,我發現IE的版本檢查無法正常工作

    downloadFile: function (fileName, csvContent, exporterOlderExcelCompatibility) {
      var D = document;
      var a = D.createElement('a');
      var strMimeType = 'application/octet-stream;charset=utf-8';
      var rawFile;
      var ieVersion;

      //Check if IE9 or below
      ieVersion = this.isIE();
      if (ieVersion && ieVersion < 10) {
        var frame = D.createElement('iframe');
        document.body.appendChild(frame);

        frame.contentWindow.document.open("text/html", "replace");
        frame.contentWindow.document.write('sep=,\r\n' + csvContent);
        frame.contentWindow.document.close();
        frame.contentWindow.focus();
        frame.contentWindow.document.execCommand('SaveAs', true, fileName);

        document.body.removeChild(frame);
        return true;
      }

      // IE10+
      if (navigator.msSaveBlob) {
        return navigator.msSaveOrOpenBlob(
          new Blob(
            [exporterOlderExcelCompatibility ? "\uFEFF" : '', csvContent],
            { type: strMimeType } ),
          fileName
        );
      }

所以ieVersion返回的是true (顯然在JS中小於10 ...)

因為我一直在尋找它可以在11年內使用,所以我可以對此進行評論,並且效果很好! 但是,如果您需要它在9以下運行,則可以切換這兩個功能的順序。 截至2016年6月3日,該代碼在ui-grid.info網站上正確無誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM