Restrictions
When exporting data on the client side, the following restrictions naturally apply:
- Only XLSX files are supported.
- Exported files omit modifications made by the cell and row templates, master-detail interface, and data mapping. You can use calculated columns instead of the latter.
- Excel limits the number of grouping levels to 7, while in the DataGrid it is unlimited.
- Excel's data format support is limited to the predefined formats with exception of "largeNumber", "quarterAndYear", "second", "millisecond", "quarter", "hour", and "minute".
- Client-side exporting in IE9 and Safari on MacOS is possible only through a proxy on the server.
User Interaction
A user clicks the Export button to save an Excel file with the exported data. Data types, sorting, filtering, and grouping settings are maintained.
Client-side exporting requires referencing the JSZip library on the page. See the guides in the Installation section for more information. After that, you can enable exporting in the DataGrid by setting the export.enabled option to true.
jQuery
$(function () { $("#dataGridContainer").dxDataGrid({ // ... export: { enabled: true } }); });
Angular
<dx-data-grid ... > <dxo-export [enabled]="true"></dxo-export> </dx-data-grid>
import { DxDataGridModule } from 'devextreme-angular'; // ... export class AppComponent { // ... } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
You can disable exporting a specific column by setting its allowExporting option to false:
jQuery
$(function () { $("#dataGridContainer").dxDataGrid({ export: { enabled: true }, columns: [{ dataField: "id", allowExporting: false }, // ... ] }); });
Angular
<dx-data-grid ... > <dxo-export [enabled]="true"></dxo-export> <dxi-column dataField="id" [allowExporting]="false"></dxi-column> <!-- ... --> </dx-data-grid>
import { DxDataGridModule } from 'devextreme-angular'; // ... export class AppComponent { // ... } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
The resulting file is renamed according to the fileName option, and contains only the selected rows if you set the allowExportSelectedData option to true.
jQuery
$(function () { $("#dataGridContainer").dxDataGrid({ // ... export: { enabled: true, allowExportSelectedData: true, fileName: "NewFileName" } }); });
Angular
<dx-data-grid ... > <dxo-export [enabled]="true" [allowExportSelectedData]="true" fileName="NewFileName"> </dxo-export> </dx-data-grid>
import { DxDataGridModule } from 'devextreme-angular'; // ... export class AppComponent { // ... } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
API
Call exportToExcel(selectionOnly) method to export data programmatically. When the selectionOnly parameter is false, the method exports all rows; when true - only the selected ones.
jQuery
// Exports selected rows $("#dataGridContainer").dxDataGrid("instance").exportToExcel(true);
Angular
import { ..., ViewChild } from '@angular/core'; import { DxDataGridModule, DxDataGridComponent } from 'devextreme-angular'; // ... export class AppComponent { @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent; exportSelectedData () { this.dataGrid.instance.exportToExcel(true); }; } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
You can customize data before exporting by specifying the customizeExportData function. See an example in its description.
Events
The DataGrid raises the following export-related events:
exporting
Allows you to request export details or prevent export. Can also be used to adjust grid columns before exporting.exported
Allows you to notify an end user when exporting is completed.fileSaving
Allows you to access the exported data in the BLOB format and/or prevent it from being saved on the user's local storage.
You can handle these events with functions. Assign the handling functions to the onExporting, onExported and onFileSaving options when you configure the widget if they are going to remain unchanged at runtime.
jQuery
$(function() { $("#dataGridContainer").dxDataGrid({ // ... onExporting: function (e) { // Handler of the "exporting" event }, onExported: function (e) { // Handler of the "exported" event }, onFileSaving: function (e) { // Handler of the "fileSaving" event } }); });
Angular
<dx-data-grid ... (onExporting)="onExporting($event)" (onExported)="onExported($event)" (onFileSaving)="onFileSaving($event)"> </dx-data-grid>
import { DxDataGridModule } from 'devextreme-angular'; // ... export class AppComponent { onExporting (e) { // Handler of the "exporting" event }; onExported (e) { // Handler of the "exported" event }; onFileSaving (e) { // Handler of the "fileSaving" event } } @NgModule({ imports: [ // ... DxDataGridModule ], // ... })
Otherwise (or if you need several handlers for a single event), subscribe to the export-related events using the on(eventName, eventHandler) method. This approach is more typical of jQuery.
var exportedHandler1 = function (e) { // First handler of the "exported" event }; var exportedHandler2 = function (e) { // Second handler of the "exported" event }; $("#dataGridContainer").dxDataGrid("instance") .on("exported", exportedHandler1) .on("exported", exportedHandler2);
See Also
- Handle Events: jQuery | Angular | AngularJS | Knockout | ASP.NET MVC
ASPx
using System; using System.Web; namespace ExportService { public class ExportHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { if(context.Request.Form["contentType"] != null && context.Request.Form["fileName"] != null && context.Request.Form["data"] != null) { context.Response.Clear(); context.Response.ContentType = context.Request.Form["contentType"].ToString(); context.Response.Charset = "UTF-8"; context.Response.Expires = 0; context.Response.AppendHeader("Content-transfer-encoding", "binary"); context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + context.Request.Form["fileName"].ToString()); context.Response.BinaryWrite(Convert.FromBase64String(context.Request.Form["data"].ToString())); context.Response.Flush(); context.Response.End(); } } public bool IsReusable { get { return false; } } } }
Imports System Imports System.Web Namespace ExportService Public Class ExportHandler Implements IHttpHandler Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest If context.Request.Form("contentType") IsNot Nothing AndAlso context.Request.Form("fileName") IsNot Nothing AndAlso context.Request.Form("data") IsNot Nothing Then context.Response.Clear() context.Response.ContentType = context.Request.Form("contentType").ToString() context.Response.Charset = "UTF-8" context.Response.Expires = 0 context.Response.AppendHeader("Content-transfer-encoding", "binary") context.Response.AppendHeader("Content-Disposition", "attachment; filename=" & context.Request.Form("fileName").ToString()) context.Response.BinaryWrite(Convert.FromBase64String(context.Request.Form("data").ToString())) context.Response.Flush() context.Response.End() End If End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class End Namespace
PHP
<?php if(!empty($_POST["data"]) && !empty($_POST["contentType"]) && !empty($_POST["fileName"])) { header("Access-Control-Allow-Origin: *"); header("Content-type: {$_POST['contentType']};\n"); header("Content-Transfer-Encoding: binary"); header("Content-length: ".strlen($_POST['data']).";\n"); header("Content-disposition: attachment; filename=\"{$_POST['fileName']}\""); die(base64_decode($_POST["data"])); } ?>
If you have technical questions, please create a support ticket in the DevExpress Support Center.
We appreciate your feedback.