我正在尝试在ng-grid csv export plugin中解决TODO:
“为IE用户添加一个带有URL的配置选项。该URL应接受有效负载中带有JSON编码对象的POST请求并返回CSV。这是必要的,因为IE不允许您从数据中下载-uri link“
然而,由于我对AngularJS,ng-grid和ng-grid插件的理解有限,我正在努力解决如何从插件中访问$ http服务(我需要用来发布数据)。我想我需要注入它,但到目前为止我尝试的所有内容都失败了。
我打算将这样的内容附加到IE中的CSV导出按钮,同时将其保留在其他浏览器中:
//post data to IEUrl
$http({
url: opts.iEUrl,
method: "POST",
data: csvData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).error(function(data, status, headers, config) {
$window.alert(status);
});
但到目前为止,即使访问$ http也打败了我!
编辑:战斗但不是战争(2天后):
所以,事实证明我正在过度思考它,为了获得$ http,$ window等,通过插件,他们只需要注入启动ng-grid的控制器然后通过:
var csvOpts = { columnOverrides: { obj: function (o) {
return o.no + '|' + o.timeOfDay + '|' + o.E + '|' + o.S+ '|' + o.I+ '|' + o.pH+ '|' + o.v;
} },
iEUrl: 'downloads/download_as_csv'
};
$scope.gridOptions = {
data: 'experiment.runs',
showGroupPanel: true,
plugins: [new ngGridCsvExportPlugin(csvOpts,$http,$window,$compile,$filter)]
然而,当事情变得困难的时候。事实证明,作为ajax请求的结果,不可能导致文件被下载,而无需额外的诡计 - 请求很好地返回了csv数据,但是没有触发下载。
所以,用$ http失败了,我以为我会创建一个表单,将csv数据放入textarea,然后像我的PHP操作一样正常发布数据:
var fp = grid.$root.find(".ngFooterPanel");
if(isIEAndUrlProvided){
var csvDataLinkPrevious = grid.$root.find('.ngFooterPanel .csv-data-form');
if (csvDataLinkPrevious != null) {csvDataLinkPrevious.remove() ; }
fp.append($compile(angular.element('<form class="csv-data-form" name="csvDataForm" action="'+opts.iEUrl+'">'))(scope));
var csvDataLinkCurrent = grid.$root.find('.ngFooterPanel .csv-data-form');
csvDataLinkCurrent.append($compile(angular.element('<textarea form="csvDataForm" class="csv-data-form">csvData</textarea>'))(scope));
csvDataLinkCurrent.append($compile(angular.element('<input class="csv-data-form" type="submit" value="CSV Export">'))(scope));
}
else {
var csvDataLinkPrevious = grid.$root.find('.ngFooterPanel .csv-data-link-span');
if (csvDataLinkPrevious != null) {csvDataLinkPrevious.remove() ; }
var csvDataLinkHtml = "<span class=\"csv-data-link-span pull-right\">";
csvDataLinkHtml += "<br><a href=\"data:text/csv;charset=UTF-8,";
csvDataLinkHtml += encodeURIComponent(csvData);
csvDataLinkHtml += "\" download=\"Export.csv\" class=\"btn btn-default btn-xs\" role=\"button\">CSV Export</a></br></span>" ;
fp.append(csvDataLinkHtml);
}
这肯定很贴近动作并允许文件下载...但它是空的 - 由于某种原因,我只是无法获得实际数据发布...所以,我恐怕我有放弃了csv导出插件,并将其留给比我更有能力的人。
编辑:一个疯狂的机智(2天后):
相反,我已经保存了每次在cookie中更改时填充网格的数据(my app完全是客户端的,这样可以防止在页面刷新时数据丢失)。因此,当我在IE中关闭我的csv文件下载请求时,我现在正在阅读PHP中的cookie并使用它来创建csv文件。我知道一个警察,但我已经没时间了,而且有效。
FWIW,修改后的插件如下:
function ngGridCsvExportPlugin (opts, $http,$window,$compile,$filter) {
var self = this;
self.grid = null;
self.scope = null;
self.init = function(scope, grid, services) {
self.grid = grid;
self.scope = scope;
//self.$http = services.http;
function showDs() {
var keys = [];
var downloadNotSupportedAndUrlProvided = false;
//test for support of download attribute: http://stackoverflow.com/questions/12112844/how-to-detect-support-for-the-html5-download-attribute
var a = document.createElement('a');
if(opts != null && opts.iEUrl !=null && typeof a.download == "undefined")downloadNotSupportedAndUrlProvided=true;//DY
for (var f in grid.config.columnDefs) { keys.push(grid.config.columnDefs[f].field);}
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) {
csvData += '"' + csvStringify(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]]);
}
else {
curCellRaw = gridData[gridRow][keys[k]];
}
csvData += '"' + csvStringify(curCellRaw) + '",';
}
csvData = swapLastCommaForNewline(csvData);
}
var fp = grid.$root.find(".ngFooterPanel");
var csvDataLinkPrevious = grid.$root.find('.ngFooterPanel .csv-data-link-span');
if (csvDataLinkPrevious != null) {csvDataLinkPrevious.remove() ; }
if(gridData.length>0){
if(downloadNotSupportedAndUrlProvided){
fp.append($compile(angular.element('<span class=\"csv-data-link-span pull-right\">'))(scope));
var csvDataSpan = grid.$root.find('.ngFooterPanel .csv-data-link-span');
csvDataSpan.append($compile(angular.element('<form class="csv-data-form" name="csvDataForm" action="'+opts.iEUrl+'">'))(scope));
var csvDataForm = grid.$root.find('.ngFooterPanel .csv-data-form');
csvDataForm.append($compile(angular.element('<input class="btn-default btn-xs" type="submit" value="CSV Export">'))(scope));
}
else {
var csvDataLinkHtml = "<span class=\"csv-data-link-span pull-right\">";
csvDataLinkHtml += "<br><a href=\"data:text/csv;charset=UTF-8,";
csvDataLinkHtml += encodeURIComponent(csvData);
csvDataLinkHtml += "\" download=\"Export.csv\" class=\"btn btn-default btn-xs\" role=\"button\">CSV Export</a></br></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;
};
if (opts.customDataWatcher) {
scope.$watch(opts.customDataWatcher, showDs);
} else {
scope.$watch(scope.catHashKeys, showDs);
}
scope.downloadCsv = function(){
$http({
url: opts.iEUrl,
method: 'POST',
data: $filter('json')(scope.csvData),
//headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).error(function(data, status, headers, config) {
$window.alert(status);
});
};
};
}
答案 0 :(得分:1)
这不是必需的。修改插件以使用FileSaver.js并使用类似:
的内容
// now save to a file!
var getArrayBuffer = function() {
var data = csvData, len = data.length,
ab = new ArrayBuffer(len), u8 = new Uint8Array(ab);
while(len--) u8[len] = data.charCodeAt(len);
return ab;
};
var getBlob = function() {
return new Blob([getArrayBuffer()], { type : "text/csv" });
},
saveAs(getBlob(), fileName);
&#13;