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 |5 Answers
Reset to default 5You 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)
.
params.data.color
? – Paritosh Commented May 5, 2018 at 17:55params.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