Print in React Spreadsheet component

20 Jan 202324 minutes to read

You can use the print method by importing from ej2-base package. Here, the Select event in the dropdown and the dataBound event are used to print the single/multiple sheets of data. To print the single/multiple sheets, use the dropdown button and select the Print (or) Print All option. In the following sample, you can be able to print the single/multiple sheets.

import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent, SheetsDirective, SheetDirective, RangesDirective } from '@syncfusion/ej2-react-spreadsheet';
import { RangeDirective, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-spreadsheet';
import { DropDownButtonComponent } from '@syncfusion/ej2-react-splitbuttons';
import { print } from '@syncfusion/ej2-base';
import { budgetData, salaryData, printElement } from './datasource';

function App() {
    const spreadsheetRef = React.useRef(null);
    const items = [
        { text: "Print" },
        { text: "Print All" }
    ];
    let isPrint = false;
    const dataBound = () => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet && isPrint) {
            printElement.querySelector(".e-sheet-content").innerHTML += document.querySelector(".e-sheet-content").outerHTML;
            let usedRange = spreadsheet.getActiveSheet().usedRange;
            let tbody = printElement.querySelector('.e-sheet-content').children[spreadsheet.activeSheetIndex].querySelector('tbody');
            for (let i = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                    tbody.getElementsByClassName('e-row')[i].remove();
                }
            }
            let sheets = spreadsheet.sheets;
            if (sheets.length - 1 === spreadsheet.activeSheetIndex) {
                let count = printElement.querySelector(".e-sheet-content").childElementCount;
                if (count > 1) {
                    for (let i = 0; i < count; i++) {
                        (printElement.querySelector('.e-sheet-content').children[i].getElementsByClassName('e-virtualtrack')[0]).style.height = 'auto';
                        printElement.querySelector('.e-sheet-content').children[i].setAttribute('style', 'page-break-after: always;')
                    }
                }
                print(printElement);
                isPrint = false;
                printElement.querySelector(".e-sheet-content").innerHTML = '';
            } else {
                if (sheets[spreadsheet.activeSheetIndex + 1]) {
                    spreadsheet.goTo(sheets[spreadsheet.activeSheetIndex + 1].name + "!A1");
                }
            }
        }
    };
    React.useEffect(() => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet) {
            spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'A1:D1');
            spreadsheet.cellFormat({ fontWeight: 'bold' }, 'A11:D11');
            spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'Salary!A1:D1');
        }
    }, []);
    const itemSelect = (args) => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet) {
            if (args.item.text === 'Print') {
                printElement.querySelector(".e-sheet-content").innerHTML = document.querySelector(".e-sheet-content").outerHTML; //  To add the spreadsheet table
                let usedRange = spreadsheet.getActiveSheet().usedRange;
                let tbody = printElement.querySelector('tbody');
                for (let i = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                    if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                        tbody.getElementsByClassName('e-row')[i].remove();
                    }
                }
                (printElement.querySelector('.e-sheet-content').children[0].getElementsByClassName('e-virtualtrack')[0]).style.height = 'auto';
                print(printElement);
                printElement.querySelector(".e-sheet-content").innerHTML = '';
            }
            if (args.item.text === 'Print All') {
                let sheets = spreadsheet.sheets;
                if (spreadsheet.activeSheetIndex === 0) {
                    printElement.querySelector(".e-sheet-content").innerHTML = document.querySelector(".e-sheet-content").outerHTML; //  To add the spreadsheet table
                    let usedRange = spreadsheet.getActiveSheet().usedRange;
                    let tbody = printElement.querySelector('tbody');
                    for (let i = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                        if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                            tbody.getElementsByClassName('e-row')[i].remove();
                        }
                    }
                    if (sheets[spreadsheet.activeSheetIndex + 1]) {
                        spreadsheet.goTo(sheets[spreadsheet.activeSheetIndex + 1].name + "!A1");
                        isPrint = true;
                    } else {
                        print(printElement);
                        printElement.querySelector(".e-sheet-content").innerHTML = '';
                    }
                } else {
                    if (sheets[0]) {
                        spreadsheet.goTo(sheets[0].name + "!A1");
                        isPrint = true;
                    }
                }
            }
        }
    };

    return (
        <div>
            <DropDownButtonComponent items={items} select={itemSelect}> Print </DropDownButtonComponent>
            <SpreadsheetComponent ref={spreadsheetRef} dataBound={dataBound} >
                <SheetsDirective>
                    <SheetDirective name={"Budget"}>
                        <RangesDirective>
                            <RangeDirective dataSource={budgetData}></RangeDirective>
                        </RangesDirective>
                        <ColumnsDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                        </ColumnsDirective>
                    </SheetDirective>
                    <SheetDirective name={"Salary"}>
                        <RangesDirective>
                            <RangeDirective dataSource={salaryData}></RangeDirective>
                        </RangesDirective>
                        <ColumnsDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                        </ColumnsDirective>
                    </SheetDirective>
                </SheetsDirective>
            </SpreadsheetComponent>
        </div>
    );
};
export default App;

const root = createRoot(document.getElementById('root'));
root.render(<App />);
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent, SheetsDirective, SheetDirective, RangesDirective, UsedRangeModel, SheetModel, MenuSelectEventArgs } from '@syncfusion/ej2-react-spreadsheet';
import { RangeDirective, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-spreadsheet';
import { DropDownButtonComponent, ItemModel } from '@syncfusion/ej2-react-splitbuttons';
import { print } from '@syncfusion/ej2-base';
import { budgetData, salaryData, printElement } from './datasource';

function App() {
    const spreadsheetRef = React.useRef<SpreadsheetComponent>(null);
    const items: ItemModel[] = [
        { text: "Print" },
        { text: "Print All" }
    ];
    let isPrint: boolean = false;
    const dataBound = (): void => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet && isPrint) {
            printElement.querySelector(".e-sheet-content").innerHTML += document.querySelector(".e-sheet-content").outerHTML;
            let usedRange: UsedRangeModel = spreadsheet.getActiveSheet().usedRange as UsedRangeModel;
            let tbody: HTMLTableSectionElement = printElement.querySelector('.e-sheet-content').children[spreadsheet.activeSheetIndex].querySelector('tbody') as HTMLTableSectionElement;
            for (let i: number = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                    tbody.getElementsByClassName('e-row')[i].remove();
                }
            }
            let sheets: SheetModel[] = spreadsheet.sheets;
            if (sheets.length - 1 === spreadsheet.activeSheetIndex) {
                let count: number = printElement.querySelector(".e-sheet-content").childElementCount;
                if (count > 1) {
                    for (let i: number = 0; i < count; i++) {
                        (printElement.querySelector('.e-sheet-content').children[i].getElementsByClassName('e-virtualtrack')[0] as HTMLElement).style.height = 'auto';
                        printElement.querySelector('.e-sheet-content').children[i].setAttribute('style', 'page-break-after: always;')
                    }
                }
                print(printElement);
                isPrint = false;
                printElement.querySelector(".e-sheet-content").innerHTML = '';
            } else {
                if (sheets[spreadsheet.activeSheetIndex + 1]) {
                    spreadsheet.goTo(sheets[spreadsheet.activeSheetIndex + 1].name + "!A1");
                }
            }
        }
    };
    React.useEffect(() => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet) {
            spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'A1:D1');
            spreadsheet.cellFormat({ fontWeight: 'bold' }, 'A11:D11');
            spreadsheet.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'Salary!A1:D1');
        }
    }, []);
    const itemSelect = (args: MenuSelectEventArgs): void => {
        let spreadsheet = spreadsheetRef.current;
        if (spreadsheet) {
            if (args.item.text === 'Print') {
                printElement.querySelector(".e-sheet-content").innerHTML = document.querySelector(".e-sheet-content").outerHTML; //  To add the spreadsheet table
                let usedRange: UsedRangeModel = spreadsheet.getActiveSheet().usedRange as UsedRangeModel;
                let tbody: HTMLTableSectionElement = printElement.querySelector('tbody') as HTMLTableSectionElement;
                for (let i: number = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                    if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                        tbody.getElementsByClassName('e-row')[i].remove();
                    }
                }
                (printElement.querySelector('.e-sheet-content').children[0].getElementsByClassName('e-virtualtrack')[0] as HTMLElement).style.height = 'auto';
                print(printElement);
                printElement.querySelector(".e-sheet-content").innerHTML = '';
            }
            if (args.item.text === 'Print All') {
                let sheets: SheetModel[] = spreadsheet.sheets;
                if (spreadsheet.activeSheetIndex === 0) {
                    printElement.querySelector(".e-sheet-content").innerHTML = document.querySelector(".e-sheet-content").outerHTML; //  To add the spreadsheet table
                    let usedRange: UsedRangeModel = spreadsheet.getActiveSheet().usedRange as UsedRangeModel;
                    let tbody: HTMLTableSectionElement = printElement.querySelector('tbody') as HTMLTableSectionElement;
                    for (let i: number = tbody.getElementsByClassName('e-row').length; i >= 0; i--) {
                        if (tbody.getElementsByClassName('e-row')[i] && parseInt(tbody.getElementsByClassName('e-row')[i].getAttribute('aria-rowindex')) > usedRange.rowIndex + 1) {
                            tbody.getElementsByClassName('e-row')[i].remove();
                        }
                    }
                    if (sheets[spreadsheet.activeSheetIndex + 1]) {
                        spreadsheet.goTo(sheets[spreadsheet.activeSheetIndex + 1].name + "!A1");
                        isPrint = true;
                    } else {
                        print(printElement);
                        printElement.querySelector(".e-sheet-content").innerHTML = '';
                    }
                } else {
                    if (sheets[0]) {
                        spreadsheet.goTo(sheets[0].name + "!A1");
                        isPrint = true;
                    }
                }
            }
        }
    };

    return (
        <div>
            <DropDownButtonComponent items={items} select={itemSelect}> Print </DropDownButtonComponent>
            <SpreadsheetComponent ref={spreadsheetRef} dataBound={dataBound} >
                <SheetsDirective>
                    <SheetDirective name={"Budget"}>
                        <RangesDirective>
                            <RangeDirective dataSource={budgetData}></RangeDirective>
                        </RangesDirective>
                        <ColumnsDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                        </ColumnsDirective>
                    </SheetDirective>
                    <SheetDirective name={"Salary"}>
                        <RangesDirective>
                            <RangeDirective dataSource={salaryData}></RangeDirective>
                        </RangesDirective>
                        <ColumnsDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                            <ColumnDirective width={100}></ColumnDirective>
                        </ColumnsDirective>
                    </SheetDirective>
                </SheetsDirective>
            </SpreadsheetComponent>
        </div>
    );
};
export default App;

const root = createRoot(document.getElementById('root')!);
root.render(<App />);
import { createElement } from '@syncfusion/ej2-base';
export let budgetData = [
    {
        "Expense Type": "Housing",
        "Projected Cost": 7000,
        "Actual Cost": 7500,
        "Difference": -500,
    },
    {
        "Expense Type": "Transportation",
        "Projected Cost": 500,
        "Actual Cost": 500,
        "Difference": 0,
    },
    {
        "Expense Type": "Insurance",
        "Projected Cost": 1000,
        "Actual Cost": 1000,
        "Difference": 0,
    },
    {
        "Expense Type": "Food",
        "Projected Cost": 2000,
        "Actual Cost": 1800,
        "Difference": 200,
    },
    {
        "Expense Type": "Pets",
        "Projected Cost": 300,
        "Actual Cost": 200,
        "Difference": 100,
    },
    {
        "Expense Type": "Personel Care",
        "Projected Cost": 500,
        "Actual Cost": 500,
        "Difference": 0,
    }, {
        "Expense Type": "Loan",
        "Projected Cost": 1000,
        "Actual Cost": 1000,
        "Difference": 0,
    }, {
        "Expense Type": "Tax",
        "Projected Cost": 200,
        "Actual Cost": 200,
        "Difference": 0,
    }, {
        "Expense Type": "Savings",
        "Projected Cost": 1000,
        "Actual Cost": 900,
        "Difference": 100,
    },
    {
        "Expense Type": "Total",
        "Projected Cost": 13500,
        "Actual Cost": 13600,
        "Difference": -100,
    }
];
export let salaryData = [
    {
        "Earnings": "Basic",
        "Credit Amount": 20000,
        "Deductions": "Provident Fund",
        "Debit Amount": 2400,
    },
    {
        "Earnings": "HRA",
        "Credit Amount": 8000,
        "Deductions": "ESI",
        "Debit Amount": 0,
    },
    {
        "Earnings": "Special Allowance",
        "Credit Amount": 25000,
        "Deductions": "Professional Tax",
        "Debit Amount": 200,
    },
    {
        "Earnings": "Incentives",
        "Credit Amount": 2000,
        "Deductions": "TDS",
        "Debit Amount": 2750,
    },
    {
        "Earnings": "Bonus",
        "Credit Amount": 1500,
        "Deductions": "Other Deduction",
        "Debit Amount": 0,
    },
    {
        "Earnings": "Total Earnings",
        "Credit Amount": 56500,
        "Deductions": "Total Deductions",
        "Debit Amount": 5350,
    }
];
export let printElement = createElement("div", {
    className: "e-sheet-panel",
    innerHTML: '<div class="e-spreadsheet-print"></div><div class="e-sheet"><div class="e-main-panel style="height:100%" style="overflow: unset"><div class="e-sheet-content" ></div></div></div>'
}); // creating same hierarchy of element as DOM
import { createElement, getComponent } from '@syncfusion/ej2-base';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';

export let budgetData: Object[] = [
    {
      "Expense Type": "Housing",
      "Projected Cost": 7000,
      "Actual Cost": 7500,
      "Difference": -500,
    },
    {
      "Expense Type": "Transportation",
      "Projected Cost": 500,
      "Actual Cost": 500,
      "Difference": 0,
    },
    {
      "Expense Type": "Insurance",
      "Projected Cost": 1000,
      "Actual Cost": 1000,
      "Difference": 0,
    },
    {
      "Expense Type": "Food",
      "Projected Cost": 2000,
      "Actual Cost": 1800,
      "Difference": 200,
    },
    {
      "Expense Type": "Pets",
      "Projected Cost": 300,
      "Actual Cost": 200,
      "Difference": 100,
    },
    {
      "Expense Type": "Personel Care",
      "Projected Cost": 500,
      "Actual Cost": 500,
      "Difference": 0,
    },{
      "Expense Type": "Loan",
      "Projected Cost": 1000,
      "Actual Cost": 1000,
      "Difference": 0,
    },{
      "Expense Type": "Tax",
      "Projected Cost": 200,
      "Actual Cost": 200,
      "Difference": 0,
    },{
      "Expense Type": "Savings",
      "Projected Cost": 1000,
      "Actual Cost": 900,
      "Difference": 100,
    },
    {
      "Expense Type": "Total",
      "Projected Cost": 13500,
      "Actual Cost": 13600,
      "Difference": -100,
    }
  ]

  export let salaryData: Object[] = [
    {
      "Earnings": "Basic",
      "Credit Amount": 20000,
      "Deductions": "Provident Fund",
      "Debit Amount": 2400,
    },
    {
      "Earnings": "HRA",
      "Credit Amount": 8000,
      "Deductions": "ESI",
      "Debit Amount": 0,
    },
    {
      "Earnings": "Special Allowance",
      "Credit Amount": 25000,
      "Deductions": "Professional Tax",
      "Debit Amount": 200,
    },
    {
      "Earnings": "Incentives",
      "Credit Amount": 2000,
      "Deductions": "TDS",
      "Debit Amount": 2750,
    },
    {
      "Earnings": "Bonus",
      "Credit Amount": 1500,
      "Deductions": "Other Deduction",
      "Debit Amount": 0,
    },
    {
      "Earnings": "Total Earnings",
      "Credit Amount": 56500,
      "Deductions": "Total Deductions",
      "Debit Amount": 5350,
    }
  ]

  export let printElement: HTMLElement = createElement("div", {
    className: "e-sheet-panel",
    innerHTML:
        '<div class="e-spreadsheet-print"></div><div class="e-sheet"><div class="e-main-panel style="height:100%" style="overflow: unset"><div class="e-sheet-content" ></div></div></div>'
    }); // creating same hierarchy of element as DOM