如何将$ http服务注入ng-grid csv export插件

时间:2014-02-10 17:29:25

标签: angularjs export-to-csv ng-grid

我正在尝试在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);
        });
    };

};

}

1 个答案:

答案 0 :(得分:1)

这不是必需的。修改插件以使用FileSaver.js并使用类似:

的内容

&#13;
&#13;
 	// 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;
&#13;
&#13;