最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Export data in ag-grid for cell renderer - Stack Overflow

programmeradmin2浏览0评论

I'm using ag-grid and I have a column definition as following :

{
    headerName: "Color",
    valueGetter: function (params) {
        return JSON.parse(params.data.color).name;
    },
    field: 'color',
    cellRenderer: function (params) {
        if (angular.isDefined(params.data) && angular.isDefined(params.data.color)) {
            var color = JSON.parse(params.data.color);
            return '<div style="width: 50px; height: 18px; background-color:' + color.htmlValue + ';"></div>';
        }
    },
    suppressMenu: true,
    suppressSorting: true
}

When I export the grid in CSV format, I get undefined for the color column, which is a cell renderer, I searched for a solution for this and I found this in the official documentation :

The raw values, and not the result of cell renderer, will get used, meaning:

  • Cell Renderers will NOT be used.
  • Value Getters will be used.
  • Cell Formatters will NOT be used (use processCellCallback instead).

As you can see I'm already using a valueGetter but I always get undefined in the exported data for the color column.

How can I solve this ?

I'm using ag-grid and I have a column definition as following :

{
    headerName: "Color",
    valueGetter: function (params) {
        return JSON.parse(params.data.color).name;
    },
    field: 'color',
    cellRenderer: function (params) {
        if (angular.isDefined(params.data) && angular.isDefined(params.data.color)) {
            var color = JSON.parse(params.data.color);
            return '<div style="width: 50px; height: 18px; background-color:' + color.htmlValue + ';"></div>';
        }
    },
    suppressMenu: true,
    suppressSorting: true
}

When I export the grid in CSV format, I get undefined for the color column, which is a cell renderer, I searched for a solution for this and I found this in the official documentation :

The raw values, and not the result of cell renderer, will get used, meaning:

  • Cell Renderers will NOT be used.
  • Value Getters will be used.
  • Cell Formatters will NOT be used (use processCellCallback instead).

As you can see I'm already using a valueGetter but I always get undefined in the exported data for the color column.

How can I solve this ?

Share Improve this question asked May 3, 2018 at 11:05 Renaud is Not Bill GatesRenaud is Not Bill Gates 2,08438 gold badges115 silver badges211 bronze badges 3
  • Could you debug and show us what's there in params.data.color? – Paritosh Commented May 5, 2018 at 17:55
  • @Paritosh When the grid is loaded params.data.color has a value but when I call the export function, I get undefined in the cellRenderer – Renaud is Not Bill Gates Commented May 7, 2018 at 9:01
  • Anyway to get it without using the Enterprise (paid version of ag-grid)??? – Jmainol Commented May 18, 2023 at 9:38
Add a comment  | 

5 Answers 5

Reset to default 5

You could solve it by using processCellCallback when exporting to CSV. This way you can see and control exactly what is going to be exported.

Besides the column definition, you can pass other parameters to your grid options.

From ag-grid docs: What gets exported

  • The raw values, and not the result of cell renderer, will get used, meaning:

    • ...
    • Cell Formatters will NOT be used (use processCellCallback instead).

So, let's say that you have your column definition in a variable called columnDefs. Now you pass that to your gridOptions.

const gridOptions = {
  columnDefs: columnDefs,
}

The latter code should work. So, now you want to handle the clicking on CSV Export on the context menu (You can also do it with a custom button if you may).

Export to CSV:

Now you have to add the provided getContextMenuItems function to you gridOptions object. For more info: Configuring the Context Menu

const gridOptions = {
  columnDefs: columnDefs,
  getContextMenuItems() {
    return [
      {
        name: 'CSV Export',
        action: function(params) {
          gridOptions.api.exportDataAsCsv({
            processCellCallback: function(cell) {
              // Manipulate the value however you need.
              return cell.value;
            },
          });
        },
      },
    ];
  },
};

The idea is to get the CSV Export and programmatically add what you need to happen in the action. On the action, what you need is to call the exportDataAsCsv function from the gridOptions.api. Now (I know this is a ton of information) one of the options you have is to include your processCellCallback function where you can make sure you pass the cell value. Doing so is very useful because you can manipulate the value however you may need (e.g. Adding a $ sign to a number that is supposed to be money).

Custom button:

There is not much to say in the case you need a custom button. The only thing you would need to do is make sure you call the exportDataAsCsv on the gridOptions.api when onclick event is fired.

Something like:

onClick() {
  gridOptions.api.exportDataAsCsv({
    processCellCallback: ...
  });
}

As another answer mentions, the ag-grid docs specifically state "Cell Renderers will NOT be used": https://www.ag-grid.com/javascript-grid-excel/#what-gets-exported

I did a workaround that calls the cellRenderer from the processCellCallback function, like this:

processCellCallback: function (cell) {
    var cellVal = cell.value;
    if(_.get(cell, 'column.colDef.cellRenderer')) {
        cellVal = cell.column.colDef.cellRenderer({value: cell.value});
    }
    return cellVal;
}      

A lil late to the party but I recently had the same inconvenience, missing the raw values because four columns needed the cellRenderer and as you know per the docs those values will not be used. In my example I needed to plug in the raw values for in_progress, complete, unanswered, & needs_review

gridApi.exportDataAsExcel({
  ...
  processCellCallback: (params) => processCells(params)
});


const processCells = (cell) =>  {
    let cellVal = cell.value;
    const { 
      in_progress, 
      complete, 
      unanswered, 
      needs_review 
    } = cell.node.data.percentageStatus; // raw data source

    if(!cell.value){ // for the 4 cols this was always undefined
      switch(cell.column.colId){
        case "in_progress":
          cellVal = in_progress;
          break;
        case "completed":
          cellVal = complete;
          break;
        case "unanswered":
          cellVal = unanswered;
          break;
        case "needs_review":
          cellVal = needs_review;
          break;
        default:
          cellVal = "n/a";
      }
    }
    return cellVal;
  } 

I've found these answers a little confusing. Hoping to help the next dev looking into this. Vue JS with Vux store.

const actions = {
exportPurchaseOrderLines({ state: stateObject }) {
    //set gridApi in state
    stateObject.gridApi.exportDataAsCsv({
        // nice file name
        fileName: `${stateObject.order.number}-export`,
        // select only selected rows
        onlySelectedAllPages: true,
        processCellCallback: (params) => {
            // use the header name to determine which column to process
            if (params.column.colDef.headerName === 'Linked bills') {
                // if there are linked bills, return the bill numbers
                if (params.node.data.bills.length > 0) {
                    return params.node.data.bills.map((bill) => bill.number).join(', ');
                }
            }
            // return all the other cells without issues
            return params.value;
        },
    });
},
// more actions .....
};

This is how I solved this issue :

When I call the export function the params arg in the cellRenderer function is not the same when the grid is loaded, the params arg looks like this when we export :

{export:true, value: "{...}"}

the value is the value in the field key, so in the cellRenderer function I had to do like this :

if(angular.isDefined(params.export)){
    return JSON.parse(params.value.slice(1, -1)).name;
}

Notice that double quotes are always added which looks weird, so when we have a string value in the field, params.value will look like this : ""theStringValue"", that's why I use params.value.slice(1, -1).

发布评论

评论列表(0)

  1. 暂无评论