我在ng-grid中使用AngularJS。ng-grid的CSV导出插件不能很好地与IE兼容,所以我们构建了一个变通方法,使用iframe来获取csv数据并进行下载。但是,即使将文件名后缀指定为.csv,exeCommand函数也仅另存为文本文件。所有数据都在文本文件中,当转换为csv时,它可以正常工作,但我们需要从一开始就将此文件作为.csv下载。
我确实发现了这个MS bug,它可能是问题的根源--很好奇是否有人能想到一个解决方案:https://support.microsoft.com/en-us/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> ";
//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
};
发布于 2015-06-26 13:48:21
这在Windows7 IE 11上适用,请参阅https://stackoverflow.com/a/24417650/1198657
if (window.navigator.msSaveOrOpenBlob) {
blobObject = new Blob([csvData]);
window.navigator.msSaveOrOpenBlob(blobObject, 'Export.csv');
}
发布于 2016-06-03 22:11:21
我实际上也有同样的问题,但在查看了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站点上的代码是正确的
https://stackoverflow.com/questions/29171802
复制相似问题