|
| 1 | +--- |
| 2 | +title: Exporting Grid Rows to Excel with Group Paging |
| 3 | +description: This article provides a workaround for exporting Grid rows to Excel when using group paging in the Grid with server operations. |
| 4 | +type: how-to |
| 5 | +page_title: How to Export Grid Rows to Excel with Group Paging |
| 6 | +slug: export-grid-rows-excel-group-paging |
| 7 | +tags: grid, export, excel, group paging |
| 8 | +res_type: kb |
| 9 | +--- |
| 10 | +## Environment |
| 11 | +| Property | Value | |
| 12 | +| --- | --- | |
| 13 | +| Product | Grid for Progress Kendo UI | |
| 14 | +| Version | 2019.3.917 | |
| 15 | + |
| 16 | +## Description |
| 17 | + |
| 18 | +I want to export Grid rows to Excel, but when using group paging in the Grid with server operations, the exported file only includes the top-level grouping titles and not the actual rows. Even when opening some of the rows, they are still not exported. |
| 19 | + |
| 20 | +## Solution |
| 21 | + |
| 22 | +Exporting a [`group-paged Grid to Excel with server operations`](https://demos.telerik.com/kendo-ui/grid/grouppaging) is not officially supported. The Excel export component creates its own dataSource and is not aware of the current state of the expanded groups. This means that the exported dataSource is not able to fetch the correct ranges of data. |
| 23 | + |
| 24 | +However, there is a workaround available that allows you to export a group-paged Grid to Excel. Please note that this is not an official approach and it requires overriding internal logic, so side effects may occur. |
| 25 | + |
| 26 | +The example below demonstrates how to achieve the desired scenario. |
| 27 | + |
| 28 | +```dojo |
| 29 | + <div id="grid"></div> |
| 30 | + <script> |
| 31 | + $(document).ready(function () { |
| 32 | + $("#grid").kendoGrid({ |
| 33 | + sortable: true, |
| 34 | + columns: [{ |
| 35 | + title: "Customer ID", |
| 36 | + width: "100px", |
| 37 | + field: "customerID" |
| 38 | + }, { |
| 39 | + title: "Country", |
| 40 | + width: "100px", |
| 41 | + field: "country" |
| 42 | + }, { |
| 43 | + title: "Company Name", |
| 44 | + width: "100px", |
| 45 | + field: "companyName" |
| 46 | + }, { |
| 47 | + title: "City", |
| 48 | + width: "100px", |
| 49 | + field: "city" |
| 50 | + }, { |
| 51 | + title: "Postal Code", |
| 52 | + width: "100px", |
| 53 | + field: "postalCode" |
| 54 | + }], |
| 55 | + filterable: true, |
| 56 | + scrollable: { |
| 57 | + virtual: true, |
| 58 | + height: "400px" |
| 59 | + }, |
| 60 | + toolbar: ["excel"], |
| 61 | + dataSource: { |
| 62 | + type: 'aspnetmvc-ajax', |
| 63 | + transport: { |
| 64 | + read: { |
| 65 | + url: "https://demos.telerik.com/aspnet-core/service/api/customers" |
| 66 | + } |
| 67 | + }, |
| 68 | + pageSize: 50, |
| 69 | + page: 1, |
| 70 | + groupPaging: true, |
| 71 | + total: 0, |
| 72 | + serverPaging: true, |
| 73 | + serverSorting: true, |
| 74 | + serverFiltering: true, |
| 75 | + serverGrouping: true, |
| 76 | + serverAggregates: true, |
| 77 | + group: [{ |
| 78 | + field: "city", |
| 79 | + dir: "asc" |
| 80 | + }, { |
| 81 | + field: "companyName", |
| 82 | + dir: "asc" |
| 83 | + }], |
| 84 | + schema: { |
| 85 | + data: "data", |
| 86 | + total: "total", |
| 87 | + errors: "errors" |
| 88 | + } |
| 89 | + }, |
| 90 | + excelExport: function(e) { |
| 91 | + e.preventDefault(); |
| 92 | + var that = this; |
| 93 | + var excel = this.options.excel || {}; |
| 94 | +
|
| 95 | + var options = { |
| 96 | + columns: that.columns, |
| 97 | + dataSource: that.dataSource, |
| 98 | + allPages: excel.allPages, |
| 99 | + filterable: excel.filterable, |
| 100 | + hierarchy: excel.hierarchy, |
| 101 | + collapsible: excel.collapsible |
| 102 | + } |
| 103 | +
|
| 104 | + var book = new kendo.excel.ExcelExporter($.extend({}, options, null, { |
| 105 | + data: that.dataSource.view(), |
| 106 | + groups: that.dataSource.group(), |
| 107 | + aggregates: that.dataSource.aggregates() |
| 108 | + })).workbook(); |
| 109 | +
|
| 110 | + var workbook = new kendo.ooxml.Workbook(book); |
| 111 | +
|
| 112 | + if (!workbook.options) { |
| 113 | + workbook.options = {}; |
| 114 | + } |
| 115 | + workbook.options.skipCustomHeight = true; |
| 116 | +
|
| 117 | + workbook.toDataURLAsync().then(function (dataURI) { |
| 118 | + kendo.saveAs({ |
| 119 | + dataURI: dataURI, |
| 120 | + fileName: book.fileName || excel.fileName, |
| 121 | + proxyURL: excel.proxyURL, |
| 122 | + forceProxy: excel.forceProxy |
| 123 | + }); |
| 124 | + }); |
| 125 | + } |
| 126 | + }); |
| 127 | +
|
| 128 | + kendo.excel.ExcelExporter.fn._dataRow = function (dataItem, level, depth) { |
| 129 | + var this$1 = this; |
| 130 | +
|
| 131 | + var cells = this._createPaddingCells(level); |
| 132 | +
|
| 133 | + // grouped |
| 134 | + if (dataItem.itemCount && depth) { |
| 135 | + cells = cells.concat(this._groupHeaderCells(dataItem, level, depth)); |
| 136 | + var rows = dataItem.items ? this._dataRows(dataItem.items, level + 1) : []; |
| 137 | +
|
| 138 | + rows.unshift({ |
| 139 | + type: "group-header", |
| 140 | + cells: cells, |
| 141 | + level: this.collapsible ? level : null |
| 142 | + }); |
| 143 | +
|
| 144 | + return rows.concat(this._footer(dataItem, level)); |
| 145 | + } |
| 146 | +
|
| 147 | + var dataCells = []; |
| 148 | +
|
| 149 | + for (var cellIdx = 0; cellIdx < this.columns.length; cellIdx++) { |
| 150 | + dataCells[cellIdx] = this$1._cell(dataItem, this$1.columns[cellIdx]); |
| 151 | + } |
| 152 | +
|
| 153 | + if (this.hierarchy) { |
| 154 | + dataCells[0].colSpan = depth - level + 1; |
| 155 | + } |
| 156 | +
|
| 157 | + return [{ |
| 158 | + type: "data", |
| 159 | + cells: cells.concat(dataCells), |
| 160 | + level: this.collapsible ? level : null |
| 161 | + }]; |
| 162 | + } |
| 163 | +
|
| 164 | + kendo.excel.ExcelExporter.fn._groupHeaderCells = function (dataItem, level, depth) { |
| 165 | + var cells = []; |
| 166 | +
|
| 167 | + var column = this.allColumns.filter(function (column) { |
| 168 | + return column.field === dataItem.field; |
| 169 | + })[0] || {}; |
| 170 | +
|
| 171 | + var title = column && column.title ? column.title : dataItem.field; |
| 172 | + var template = column ? column.groupHeaderTemplate || column.groupHeaderColumnTemplate : null; |
| 173 | + var group = $.extend({ |
| 174 | + title: title, |
| 175 | + field: dataItem.field, |
| 176 | + value: column && column.values ? column.values[dataItem.value] : dataItem.value, |
| 177 | + aggregates: dataItem.aggregates, |
| 178 | + items: dataItem.items |
| 179 | + }, dataItem.aggregates[dataItem.field]); |
| 180 | +
|
| 181 | + var value = template ? template(group) : (title + ": " + (dataItem.value)); |
| 182 | +
|
| 183 | + cells.push($.extend({ |
| 184 | + value: value, |
| 185 | + background: "#dfdfdf", |
| 186 | + color: "#333", |
| 187 | + colSpan: (this.hasGroupHeaderColumn ? 1 : this.columns.length) + depth - level |
| 188 | + }, column.groupHeaderCellOptions)); |
| 189 | +
|
| 190 | + if (this.hasGroupHeaderColumn) { |
| 191 | + this.columns.forEach(function (column, index) { |
| 192 | + if (index > 0) { |
| 193 | + cells.push($.extend({ |
| 194 | + background: "#dfdfdf", |
| 195 | + color: "#333", |
| 196 | + value: column.groupHeaderColumnTemplate ? |
| 197 | + column.groupHeaderColumnTemplate($.extend({ group: group }, group, dataItem.aggregates[column.field])) : |
| 198 | + undefined |
| 199 | + }, column.groupHeaderCellOptions)); |
| 200 | + } |
| 201 | + }); |
| 202 | + } |
| 203 | +
|
| 204 | + return cells; |
| 205 | + } |
| 206 | + }); |
| 207 | + </script> |
| 208 | +``` |
| 209 | + |
| 210 | +## Notes |
| 211 | +Keep in mind that this workaround is not officially supported and may have side effects. Use it at your own discretion. |
| 212 | + |
| 213 | +## See Also |
| 214 | + |
| 215 | +* [JavaScript API Reference of the Kendo UI for jQuery Grid](/api/javascript/ui/grid) |
| 216 | +* [Grid Group Paging of Remote Data(Demo)](https://demos.telerik.com/kendo-ui/grid/grouppaging) |
0 commit comments