Client-Side Export and Printing

Although DevExtreme data visualization widgets can be displayed on any device, a user may need a widget printed or in the form of a document. For these cases, the widgets provide client-side export and printing. This guide shows how to configure these features for the user, and how to export and print a widget using the API. It also explains how to set up a server-side proxy, which is necessary if you plan to support export and printing in IE9 and Safari on MacOS.

Watch Video

User Interaction

To export or print a widget, a user clicks the "Exporting/Printing" button and selects a command from the drop-down menu. The Print command opens the browser's Print window that lets the user select preferred printing settings and send the print job to the printer. The other commands save a file of the selected format in the user's local storage.

DevExtreme HTML5 DataVisualization Charts Export Print

To enable both export and printing, assign true to the export | enabled option. If you need only export to be available to the user, disable printing by assigning false to the export | printingEnabled option.

JavaScript
$(function() {
    $("#chartContainer").dxChart({
        // ...
        export: {
            enabled: true,
            printingEnabled: false
        }
    });
});

If you want to restrict the set of formats available for export, change the export | formats array. You can also specify the default name for the exported file using the fileName option.

JavaScript
$(function() {
    $("#chartContainer").dxChart({
        // ...
        export: {
            enabled: true,
            formats: ["PNG", "JPEG"],
            fileName: "exported_chart"
        }
    });
});

To support export and printing in IE9 and Safari on MacOS, you need to set up a proxy on your server. For details, see the Set Up a Server-Side Proxy topic.

API

To export a widget using the API, call the exportTo(fileName, format) method passing the needed file name and format ("PNG", "PDF", "JPEG", "SVG" or "GIF") as the arguments. To print a widget, call the print() method. This command opens the browser's Print window.

JavaScript
var chart = $("#chartContainer").dxChart("instance");
chart.exportTo('Exported Chart', 'PDF');
chart.print();

You can also export several widgets at once using their SVG markup. Gather the markup from all required widgets by calling the DevExpress.viz.getMarkup(widgetInstances) method, and then pass the markup to the DevExpress.viz.exportFromMarkup(markup, options) method.

JavaScript
var chart1 = $("#chartContainer1").dxChart("instance");
var chart2 = $("#chartContainer2").dxChart("instance");
var chartMarkup = DevExpress.viz.getMarkup([chart1, chart2]);

DevExpress.viz.exportFromMarkup(chartMarkup, {
    height: 768,
    width: 1024,
    fileName: "Exported Charts",
    format: "PDF"
});

Events

DevExtreme data visualization widgets raise the following export-related events.

  • exporting
    Allows you to request export details or prevent export.

  • exported
    Allows you to notify an end user when export is completed.

  • fileSaving
    Allows you to access exported data in the BLOB format and/or prevent it from being saved in a file on the user's local storage.

You can handle these events with functions. If the handling functions are not going to be changed at runtime, assign them to the onExporting, onExported and onFileSaving options when you configure the widget.

JavaScript
$(function() {
    $("#chartContainer").dxChart({
        // ...
        onExporting: function (e) {
            // Handler of the "exporting" event
        },
        onExported: function (e) {
            // Handler of the "exported" event
        },
        onFileSaving: function (e) {
            // Handler of the "fileSaving" event
        }
    });
});

Otherwise, or if you need several handlers for a single event, subscribe to the export-related events using the on(eventName, eventHandler) method.

JavaScript
var exportedHandler1 = function (e) {
    // First handler of the "exported" event
};

var exportedHandler2 = function (e) {
    // Second handler of the "exported" event
};

$("#chartContainer").dxChart("instance")
    .on("exported", exportedHandler1)
    .on("exported", exportedHandler2);
See Also

Set Up a Server-Side Proxy

If you need export and printing in browsers that do not provide an API for saving files (that is, in IE9 and Safari on Mac OS), implement a server-side proxy that will stream the resulting file back to an end user in response to a POST request. The proxy implementation is different for each platform.

ASPx

C#
VB
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"]));
    } 
?>

Usage

To notify the widget that it must export the file through a proxy, specify the export | proxyUrl option.