PDF Export

The KendoReact TreeList provides options for exporting to PDF.

Getting Started

To enable the PDF export:

  1. Install kendo-react-pdf package.

    npm install @progress/kendo-react-pdf
  2. Import the TreeListPDFExport component in your React Application.

    import { TreeListPDFExport } from '@progress/kendo-react-pdf';
  3. Wrap the TreeList inside a TreeListPDFExport component.

  4. Get the ref of the TreeListPDFExport.

  5. Call the save function of the TreeListPDFExport component.

The following example demonstrates the basic implementation of the PDF export functionality of the TreeList.

import React from "react";
import ReactDOM from "react-dom";
import {
  TreeList,
  orderBy,
  filterBy,
  mapTree,
  extendDataItem,
  TreeListTextFilter,
  TreeListNumericFilter,
  TreeListDateFilter,
  TreeListBooleanFilter,
  TreeListToolbar
} from "@progress/kendo-react-treelist";
import employees from "./data";
import { TreeListPDFExport } from "@progress/kendo-react-pdf";

const subItemsField = "employees";
const expandField = "expanded";
const columns = [
  {
    field: "name",
    title: "Name",
    width: 250,
    filter: TreeListTextFilter,
    expandable: true
  },
  {
    field: "hireDate",
    title: "Hire Date",
    width: 200,
    format: "{0:d}",
    filter: TreeListDateFilter
  },
  {
    field: "timeInPosition",
    title: "Year(s) in Position",
    width: 200,
    filter: TreeListNumericFilter
  },
  {
    field: "fullTime",
    title: "Full Time",
    width: 100,
    filter: TreeListBooleanFilter
  }
];

class App extends React.Component {
  gridPDFExport;
  state = {
    data: [...employees],
    dataState: {
      sort: [{ field: "name", dir: "asc" }],
      filter: []
    },
    expanded: [1, 2, 32]
  };

  onExpandChange = e => {
    this.setState({
      expanded: e.value
        ? this.state.expanded.filter(id => id !== e.dataItem.id)
        : [...this.state.expanded, e.dataItem.id]
    });
  };

  handleDataStateChange = event => {
    this.setState({
      dataState: event.data
    });
  };

  addExpandField = dataTree => {
    const expanded = this.state.expanded;
    return mapTree(dataTree, subItemsField, item =>
      extendDataItem(item, subItemsField, {
        [expandField]: expanded.includes(item.id)
      })
    );
  };

  processData = () => {
    let { data, dataState } = this.state;
    let filteredData = filterBy(data, dataState.filter, subItemsField);
    let sortedData = orderBy(filteredData, dataState.sort, subItemsField);
    return this.addExpandField(sortedData);
  };

  render() {
    const treelist = (
      <TreeList
        style={{ maxHeight: "510px", overflow: "auto" }}
        expandField={expandField}
        subItemsField={subItemsField}
        onExpandChange={this.onExpandChange}
        sortable={{ mode: "multiple" }}
        {...this.state.dataState}
        data={this.processData()}
        onDataStateChange={this.handleDataStateChange}
        columns={columns}
        toolbar={
          <TreeListToolbar>
            <button
              title="Export PDF"
              className="k-button k-primary"
              onClick={this.exportPDF}
            >
              Export PDF
            </button>
          </TreeListToolbar>
        }
      />
    );

    return (
      <div>
        {treelist}
        <TreeListPDFExport ref={pdfExport => (this.gridPDFExport = pdfExport)}>
          {treelist}
        </TreeListPDFExport>
      </div>
    );
  }

  exportPDF = () => {
    this.gridPDFExport.save();
  };
}

ReactDOM.render(<App />, document.querySelector("my-app"));

Configuration

You can control the PDF export configuration through the arguments that are passed to the save function of the KendoReact PDF Export component.

The TreeListPDFExport enables you to:

Exporting Specific Data

To export specific data, pass the data to the save function of the TreeListPDFExport component. For example, if the TreeList has its paging enabled but you need to export all pages and all records expanded, pass the processed data to the save function.

import React from "react";
import ReactDOM from "react-dom";
import {
    TreeList,
    mapTree,
    extendDataItem,
    TreeListToolbar
} from "@progress/kendo-react-treelist";
import employees from "./data";
import { TreeListPDFExport } from "@progress/kendo-react-pdf";

import { TreeListPager } from './pager.jsx';

const subItemsField = "employees";
const expandField = "expanded";
const columns = [
    {
        field: "name",
        title: "Name",
        width: 250,
        expandable: true
    },
    {
        field: "hireDate",
        title: "Hire Date",
        width: 200,
        format: "{0:d}"
    },
    {
        field: "timeInPosition",
        title: "Year(s) in Position",
        width: 200
    },
    {
        field: "fullTime",
        title: "Full Time",
        width: 100
    }
];

class App extends React.Component {
    gridPDFExport;
    state = {
        data: [...employees],
        skip: 0,
        take: 5,
        expanded: [1, 2, 32]
    };

    onExpandChange = e => {
        this.setState({
            expanded: e.value
                ? this.state.expanded.filter(id => id !== e.dataItem.id)
                : [...this.state.expanded, e.dataItem.id]
        });
    };

    addExpandField = dataTree => {
        const expanded = this.state.expanded;
        return mapTree(dataTree, subItemsField, item =>
            extendDataItem(item, subItemsField, {
                [expandField]: expanded.includes(item.id)
            })
        );
    };

    onPageChange = (event) => {
        const { skip, take } = event;
        this.setState({ skip, take });
    }

    exportPDF = () => {
        let allDataExpanded = mapTree(this.state.data, subItemsField, item =>
            extendDataItem(item, subItemsField, {
                [expandField]: true
            })
        );
        this.gridPDFExport.save(allDataExpanded);
    };

    render() {
        const treelist = (
            <TreeList
                style={{ maxHeight: "510px", overflow: "auto" }}
                expandField={expandField}
                subItemsField={subItemsField}
                onExpandChange={this.onExpandChange}
                pager={TreeListPager}
                skip={this.state.skip}
                take={this.state.take}
                onPageChange={this.onPageChange}
                data={this.addExpandField(this.state.data)}
                columns={columns}
                toolbar={
                    <TreeListToolbar>
                        <button
                            title="Export PDF"
                            className="k-button k-primary"
                            onClick={this.exportPDF}
                        >
                            Export PDF
                        </button>
                    </TreeListToolbar>
                }
            />
        );

        return (
            <div>
                {treelist}
                <TreeListPDFExport ref={pdfExport => (this.gridPDFExport = pdfExport)} allPages={true}>
                    {treelist}
                </TreeListPDFExport>
            </div>
        );
    }
}

ReactDOM.render(<App />, document.querySelector("my-app"));

Customizing Exported Columns

The TreeListPDFExport provides the ability to add or hide some of the columns in the exported PDF file. This is done by passing the columns that have to be exported to the save function.

import React from "react";
import ReactDOM from "react-dom";
import {
  TreeList,
  orderBy,
  filterBy,
  mapTree,
  extendDataItem,
  TreeListTextFilter,
  TreeListNumericFilter,
  TreeListDateFilter,
  TreeListBooleanFilter,
  TreeListToolbar
} from "@progress/kendo-react-treelist";
import employees from "./data";
import { TreeListPDFExport } from "@progress/kendo-react-pdf";

const subItemsField = "employees";
const expandField = "expanded";
const columns = [
  {
    field: "name",
    title: "Name",
    width: 250,
    filter: TreeListTextFilter,
    expandable: true
  },
  {
    field: "hireDate",
    title: "Hire Date",
    width: 200,
    format: "{0:d}",
    filter: TreeListDateFilter
  },
  {
    field: "timeInPosition",
    title: "Year(s) in Position",
    width: 200,
    filter: TreeListNumericFilter
  },
  {
    field: "fullTime",
    title: "Full Time",
    width: 100,
    filter: TreeListBooleanFilter
  }
];

const columnsForExport = columns.slice(0,2);

class App extends React.Component {
  gridPDFExport;
  state = {
    data: [...employees],
    dataState: {
      sort: [{ field: "name", dir: "asc" }],
      filter: []
    },
    expanded: [1, 2, 32]
  };

  onExpandChange = e => {
    this.setState({
      expanded: e.value
        ? this.state.expanded.filter(id => id !== e.dataItem.id)
        : [...this.state.expanded, e.dataItem.id]
    });
  };

  handleDataStateChange = event => {
    this.setState({
      dataState: event.data
    });
  };

  addExpandField = dataTree => {
    const expanded = this.state.expanded;
    return mapTree(dataTree, subItemsField, item =>
      extendDataItem(item, subItemsField, {
        [expandField]: expanded.includes(item.id)
      })
    );
  };

  processData = () => {
    let { data, dataState } = this.state;
    let filteredData = filterBy(data, dataState.filter, subItemsField);
    let sortedData = orderBy(filteredData, dataState.sort, subItemsField);
    return this.addExpandField(sortedData);
  };

  render() {
    const treelist = (
      <TreeList
        style={{ maxHeight: "510px", overflow: "auto" }}
        expandField={expandField}
        subItemsField={subItemsField}
        onExpandChange={this.onExpandChange}
        sortable={{ mode: "multiple" }}
        {...this.state.dataState}
        data={this.processData()}
        onDataStateChange={this.handleDataStateChange}
        columns={columns}
        toolbar={
          <TreeListToolbar>
            <button
              title="Export PDF"
              className="k-button k-primary"
              onClick={this.exportPDF}
            >
              Export PDF
            </button>
          </TreeListToolbar>
        }
      />
    );

    return (
      <div>
        {treelist}
        <TreeListPDFExport ref={pdfExport => (this.gridPDFExport = pdfExport)}>
          {treelist}
        </TreeListPDFExport>
      </div>
    );
  }

  exportPDF = () => {
    this.gridPDFExport.save(this.processData(), columnsForExport);
  };
}

ReactDOM.render(<App />, document.querySelector("my-app"));

Known Limitations

For full list of the PDF export known limitations refer to the drawing package.