称为单元过滤器的Ng-grid导出。

时间:2022-08-24 11:29:30

I'm working with an ng-grid and some columns have filters applied. However, when I export to CSV right now the values are displayed without filters: a record might like like this in json:

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

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

but in the grid it is displayed as:

但在网格中显示为:

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

I'd like when I get an extract for it to appear as if the filter are applied but the only csv plugin does not seem to call cell filters, and simply returns the values in raw form. How can I invoke the filters?

我希望当我得到一个解压,让它看起来像是应用了过滤器,但唯一的csv插件似乎不调用单元格过滤器,而只是返回原始形式的值。如何调用过滤器?

4 个解决方案

#1


3  

I discovered a solution that works with ui-grid (the replacement version of ng-grid), and it's much simpler than the plugin workaround that Matt Welch had to develop for ng-grid 2.0.

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

You can specify an exporterFieldCallback in your gridOptions and then do whatever you want based on the col.name. For my use case I had user IDs, which I needed to cross reference to an array index. I'd built a cellFilter for the table, but it obviously wasn't reflected in the exported CSV until I added the exporterFieldCallback like so:

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

$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;
        }
    },
    ...
}

The callback requires the grid, row, col, and input variables, and then you can do anything inside it to return whatever values you need exported. It would be nice if there were a "use what's displayed in the grid" flag, but this is still a pretty simple solution, even if it appears to be undocumented.

回调需要网格、行、col和输入变量,然后您可以在其中做任何事情来返回您需要导出的任何值。如果有一个“使用网格中显示的内容”标志,那就太好了,但是这仍然是一个非常简单的解决方案,即使它看起来没有文档。

#2


1  

I know this question is a few months old but I was searching for the same thing and figured I'd document how I solved the problem.

我知道这个问题已经有几个月了,但我一直在寻找同样的问题,我想我应该记录下我是如何解决这个问题的。

Side note: I saw that there is an ng-grid-wysiwyg-export.js plugin in the plugins folder but I found no examples or documentation on it's use and didn't take the time to figure it out because...

附注:我看到有一个ng-grid-wysiwyg-export。插件文件夹中的js插件,但是我没有找到它使用的例子或文档,也没有花时间去理解它,因为……

I did find that there is a playground.html file in the ng-grid plugins folder that has an example for the CSV plugin. It demonstrated how to use the columnOverrides feature that you can pass into the plugin constructor via the opts parameter:

我确实发现有一个操场。在ng-grid插件文件夹中的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
};

So for the example in the question above, you can define override functions for each column that you want to apply filters on, like so:

所以对于上面问题中的例子,你可以为你想要应用过滤器的每一列定义覆盖函数,比如:

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); }
    }
};

While it's a little extra work to have to define these instead of just invoking the already-defined cellFilter from the columnDefs, this approach DOES give you the flexibility to have your exported data be slightly different than what is displayed on the screen... perhaps a more expressive date format, etc.

虽然要定义这些数据而不是仅仅从columnDefs中调用已经定义好的cellFilter要做一些额外的工作,但是这种方法确实可以使您的导出数据与屏幕上显示的数据略有不同。也许是更有表现力的日期格式,等等。

#3


1  

I developed for this a solution based on the exporterFieldCallback.

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

My idea is to DO NOT REPEAT the filter expression you already have in the columnDefs, like:

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

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

where, of course, notAvailable and readableFileSize are both custom filters defined by me and regularly used by the ui-grid.

当然,notAvailable和readableFileSize都是我定义的自定义过滤器,并且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;

}

It's poor because I'm a Javascript dummy, it works only for filters that accepts no parameter or one parameter; but can be for sure improved, I was on the rush. Also in the regex most probably there is some redundance

它很糟糕,因为我是一个Javascript伪函数,它只适用于不接受参数或一个参数的过滤器;但可以肯定的是,我是在赶时间。在regex中,很可能还有一些冗余

It takes the cellFilter if defined for the column and programmatically apply again as well. With this single generic function I added export to ALL the columns of all the ui-grids.

如果为列定义了cellFilter,它还将以编程方式再次应用。使用这个通用函数,我向所有ui-grid的所有列添加了export。

#4


0  

Based on the response from 'angelodelia'. Here is my modifed version. This would work for multiple filter with multiple parameters.

基于“angelodelia”的回应。这是我修改过的版本。这将适用于具有多个参数的多个过滤器。

 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;
        }

This generic function will help export the data as it is displayed in UI Grid (after applying the filters.)

这个通用函数将帮助导出UI网格中显示的数据(在应用过滤器之后)。

#1


3  

I discovered a solution that works with ui-grid (the replacement version of ng-grid), and it's much simpler than the plugin workaround that Matt Welch had to develop for ng-grid 2.0.

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

You can specify an exporterFieldCallback in your gridOptions and then do whatever you want based on the col.name. For my use case I had user IDs, which I needed to cross reference to an array index. I'd built a cellFilter for the table, but it obviously wasn't reflected in the exported CSV until I added the exporterFieldCallback like so:

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

$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;
        }
    },
    ...
}

The callback requires the grid, row, col, and input variables, and then you can do anything inside it to return whatever values you need exported. It would be nice if there were a "use what's displayed in the grid" flag, but this is still a pretty simple solution, even if it appears to be undocumented.

回调需要网格、行、col和输入变量,然后您可以在其中做任何事情来返回您需要导出的任何值。如果有一个“使用网格中显示的内容”标志,那就太好了,但是这仍然是一个非常简单的解决方案,即使它看起来没有文档。

#2


1  

I know this question is a few months old but I was searching for the same thing and figured I'd document how I solved the problem.

我知道这个问题已经有几个月了,但我一直在寻找同样的问题,我想我应该记录下我是如何解决这个问题的。

Side note: I saw that there is an ng-grid-wysiwyg-export.js plugin in the plugins folder but I found no examples or documentation on it's use and didn't take the time to figure it out because...

附注:我看到有一个ng-grid-wysiwyg-export。插件文件夹中的js插件,但是我没有找到它使用的例子或文档,也没有花时间去理解它,因为……

I did find that there is a playground.html file in the ng-grid plugins folder that has an example for the CSV plugin. It demonstrated how to use the columnOverrides feature that you can pass into the plugin constructor via the opts parameter:

我确实发现有一个操场。在ng-grid插件文件夹中的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
};

So for the example in the question above, you can define override functions for each column that you want to apply filters on, like so:

所以对于上面问题中的例子,你可以为你想要应用过滤器的每一列定义覆盖函数,比如:

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); }
    }
};

While it's a little extra work to have to define these instead of just invoking the already-defined cellFilter from the columnDefs, this approach DOES give you the flexibility to have your exported data be slightly different than what is displayed on the screen... perhaps a more expressive date format, etc.

虽然要定义这些数据而不是仅仅从columnDefs中调用已经定义好的cellFilter要做一些额外的工作,但是这种方法确实可以使您的导出数据与屏幕上显示的数据略有不同。也许是更有表现力的日期格式,等等。

#3


1  

I developed for this a solution based on the exporterFieldCallback.

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

My idea is to DO NOT REPEAT the filter expression you already have in the columnDefs, like:

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

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

where, of course, notAvailable and readableFileSize are both custom filters defined by me and regularly used by the ui-grid.

当然,notAvailable和readableFileSize都是我定义的自定义过滤器,并且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;

}

It's poor because I'm a Javascript dummy, it works only for filters that accepts no parameter or one parameter; but can be for sure improved, I was on the rush. Also in the regex most probably there is some redundance

它很糟糕,因为我是一个Javascript伪函数,它只适用于不接受参数或一个参数的过滤器;但可以肯定的是,我是在赶时间。在regex中,很可能还有一些冗余

It takes the cellFilter if defined for the column and programmatically apply again as well. With this single generic function I added export to ALL the columns of all the ui-grids.

如果为列定义了cellFilter,它还将以编程方式再次应用。使用这个通用函数,我向所有ui-grid的所有列添加了export。

#4


0  

Based on the response from 'angelodelia'. Here is my modifed version. This would work for multiple filter with multiple parameters.

基于“angelodelia”的回应。这是我修改过的版本。这将适用于具有多个参数的多个过滤器。

 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;
        }

This generic function will help export the data as it is displayed in UI Grid (after applying the filters.)

这个通用函数将帮助导出UI网格中显示的数据(在应用过滤器之后)。