调用单元格过滤器的Ng网格导出

时间:2014-04-28 14:24:44

标签: angularjs ng-grid angular-ui-grid

我正在使用ng-grid,并且某些列已应用过滤器。但是,当我现在导出到CSV时,显示的值没有过滤器: 记录在json中可能是这样的:

{"service_date":"2014-02-10T00:00:00.000Z",
 "service_code":"someJob3",
 "price":1234.56}

但在网格中显示为:

Service Date |Service Desc | Price
-------------------------------------
Feb 10,2014  |Some Job 3   | $1,234.56

我希望当我得到一个提取物时,它看起来好像应用了过滤器但是唯一的csv插件似乎不会调用单元格过滤器,只是以原始形式返回值。我该如何调用过滤器?

4 个答案:

答案 0 :(得分:3)

我发现了一个与ui-grid(ng-grid的替换版本)一起使用的解决方案,它比Matt Welch必须为ng-grid 2.0开发的插件解决方案简单得多。

您可以在gridOptions中指定exporterFieldCallback,然后根据col.name执行任何操作。对于我的用例,我有用户ID,我需要交叉引用数组索引。我为表格构建了一个cellFilter,但在我添加了exporterFieldCallback之前,它显然没有反映在导出的CSV中:

$scope.gridOptions = {
    ...

    exporterFieldCallback: function( grid, row, col, input ) {
        if( col.name == 'account_executive_id' || col.name == 'account_manager_id' ) {
            return adminUsers.getUserName(input);
        } else {
            return input;
        }
    },
    ...
}

回调需要grid,row,col和input变量,然后你可以在其中做任何事情来返回你需要导出的任何值。如果有一个"使用在网格中显示的内容"那将是很好的。标志,但这仍然是一个非常简单的解决方案,即使它似乎没有文档。

答案 1 :(得分:1)

我知道这个问题已经有几个月了,但我正在寻找同样的事情,并且认为我记录了我是如何解决这个问题的。

附注:我看到插件文件夹中有一个ng-grid-wysiwyg-export.js插件,但我没有找到关于它的使用的示例或文档,并且没有花时间弄清楚因为......

发现ng-grid插件文件夹中有一个playground.html文件,其中包含CSV插件的示例。它演示了如何使用 columnOverrides 功能,您可以通过opts参数传递给插件构造函数:

$scope.myData = [ 
    {hasThing: false,  obj: {a:5, b:6}, name: "Moroni", age: 50, ln: 'sdf'},
    {hasThing:  true,  obj: {a:6, b:7}, ln: "Tiasdfsdfnd", age: 43}
];

var csvOpts = { columnOverrides: { obj: function(o) { return o.a + '|' +  o.b; } } };

$scope.gridOptionsBig = {
    data: 'myData',
    plugins: [new ngGridCsvExportPlugin(csvOpts)],
    showFooter: true
};

因此,对于上述问题中的示例,您可以为要应用过滤器的每个列定义覆盖函数,如下所示:

var csvOpts = { 
    columnOverrides: {
        service_date: function(d) { return $filter('date')(d); },
        service_code: function(c) { return $filter('myCustomCamelCaseFilter')(c); },
        price: function(p) { return $filter('currency')(p); }
    }
};

虽然必须定义这些而不仅仅是从columnDefs调用已定义的cellFilter,这是一项额外的工作,但这种方法可以让您灵活地使导出的数据与屏幕上显示的数据略有不同。 ..也许是一种更具表现力的日期格式等。

答案 2 :(得分:1)

我为此开发了一个基于exporterFieldCallback的解决方案。

我的想法是不要重复columnDefs中已有的过滤器表达式,例如:

  {
    field: 'totalFileSize',
    headerCellClass: $scope.highlightFilteredHeader,
    cellFilter: "notAvailable:'N/A' | readableFileSize",
    displayName: "Total size",
    cellClass:"rightcell"
  },

当然,notAvailablereadableFileSize都是由我定义并由ui-grid经常使用的自定义过滤器。

exporterFieldCallback: function( grid, row, col, input ) {
  if (col.cellFilter!=undefined && col.cellFilter.length !=0) {
    var filters = col.cellFilter.split('|');
    for(i =0; i<filters.length;i++) {
      var pars = filters[i].match(/[^\:"']+|'([^']*)'|'([^']*)'+/g);
      var filterName= pars[0].trim();
      var filterPar = null;
      if (pars.length ==2) {
         filterPar = pars[1].slice(1, -1);
        input = $filter(filterName)( input,filterPar);
      } else {
        input = $filter(filterName)( input );
      }
    }
  }
  return input;

}

这很差,因为我是一个Javascript假人,它只适用于不接受参数或一个参数的过滤器;但可以肯定有所改善,我匆匆忙忙。同样在正则表达式中最有可能存在一些冗余

如果为列定义了cellFilter,那么它也会以编程方式再次应用。 使用这个单一的泛型函数,我添加了导出到所有ui-grid的所有列。

答案 3 :(得分:0)

根据'angelodelia&#39;的回应。这是我修改过的版本。 这适用于具有多个参数的多个过滤器。

 exporterFieldCallback: function (grid, row, col, input) {
            if (col.cellFilter) { // check if any filter is applied on the column
                var filters = col.cellFilter.split('|'); // get all the filters applied
                angular.forEach(filters, function (filter) {
                    var filterName = filter.split(':')[0]; // fetch filter name
                    var filterParams = filter.split(':').splice(1); //fetch all the filter parameters
                    filterParams.unshift(input); // insert the input element to the filter parameters list
                    var filterFn = $filter(filterName); // filter function
                    // call the filter, with multiple filter parameters. 
                    //'Apply' will call the function and pass the array elements as individual parameters to that function.
                    input = filterFn.apply(this, filterParams); 
                })
                return input;
            }
            else
                return input;
        }

此通用功能将帮助导出数据,因为它在UI网格中显示(应用过滤器后)。