首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >execCommand('SaveAs',true,'data.csv');在IE中不起作用

execCommand('SaveAs',true,'data.csv');在IE中不起作用
EN

Stack Overflow用户
提问于 2015-03-21 00:50:12
回答 2查看 3.4K关注 0票数 2

我在ng-grid中使用AngularJS。ng-grid的CSV导出插件不能很好地与IE兼容,所以我们构建了一个变通方法,使用iframe来获取csv数据并进行下载。但是,即使将文件名后缀指定为.csv,exeCommand函数也仅另存为文本文件。所有数据都在文本文件中,当转换为csv时,它可以正常工作,但我们需要从一开始就将此文件作为.csv下载。

我确实发现了这个MS bug,它可能是问题的根源--很好奇是否有人能想到一个解决方案:https://support.microsoft.com/en-us/kb/929863

谢谢!

有问题的代码:

代码语言:javascript
运行
复制
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
};
EN

回答 2

Stack Overflow用户

发布于 2015-06-26 13:48:21

这在Windows7 IE 11上适用,请参阅https://stackoverflow.com/a/24417650/1198657

代码语言:javascript
运行
复制
if (window.navigator.msSaveOrOpenBlob) {
  blobObject = new Blob([csvData]);
  window.navigator.msSaveOrOpenBlob(blobObject, 'Export.csv');
}
票数 3
EN

Stack Overflow用户

发布于 2016-06-03 22:11:21

我实际上也有同样的问题,但在查看了ui-grid的源代码(在ui-grid.js文件中)后,我发现IE的版本检查不能正常工作

代码语言:javascript
运行
复制
    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站点上的代码是正确的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29171802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档