Client-side Excel export#
When export is bounded (one page of grid data, already loaded) and server-side ExcelHandler / CsvHandler would be overkill, build the workbook in the browser using the xlsx library.
Install#
npm install xlsx file-saver
npm install -D @types/file-saverExport utility#
// src/utils/ExcelExport.ts
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
export interface ExportColumn {
key: string; // attribute name on the row object
label: string; // column header in the workbook
}
export function exportToExcel(
rows: Record<string, any>[],
columns: ExportColumn[],
fileName: string = 'export',
options?: { sheetName?: string; includeTotal?: string[] }
) {
// Map rows to labelled columns
const data = rows.map(row =>
Object.fromEntries(columns.map(c => [c.label, row[c.key] ?? '']))
);
// Optional total row
if (options?.includeTotal) {
const totals: Record<string, any> = {};
columns.forEach(c => {
if (options.includeTotal!.includes(c.key)) {
totals[c.label] = rows.reduce(
(sum, r) => sum + (Number(r[c.key]) || 0), 0
);
} else {
totals[c.label] = c === columns[0] ? 'TOTAL' : '';
}
});
data.push(totals);
}
const ws = XLSX.utils.json_to_sheet(data);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, options?.sheetName ?? 'Sheet1');
const buf = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
saveAs(new Blob([buf], { type: 'application/octet-stream' }), `${fileName}.xlsx`);
}Using it from a grid toolbar#
import { exportToExcel, type ExportColumn } from '../../utils/ExcelExport';
const exportColumns: ExportColumn[] = [
{ key: 'loginName', label: 'Email' },
{ key: 'firstName', label: 'First Name' },
{ key: 'lastName', label: 'Last Name' },
{ key: 'departmentCode', label: 'Department' },
{ key: 'status', label: 'Status' },
];
// Inside your custom DataGridControls:
const handleExport = () => {
const rows = o.queryRef?.current?.getCurrentData() ?? [];
exportToExcel(rows, exportColumns, 'employees', {
sheetName: 'Employees',
});
};
<Button onClick={handleExport}>Export Excel</Button>When to use client-side vs. server-side export#
Client-side (xlsx + file-saver) |
Server-side (CsvHandler / ExcelHandler) |
|---|---|
| Already-loaded rows (one page) | Full result set across all pages |
| No server round-trip | Streams from the database — handles millions of rows |
| Browser memory is the limit | Server memory scales independently |
| Quick to implement | Needs a dedicated handler + @CrudMapping |
Use both in the same app: the grid toolbar’s “Export current page” calls the client-side utility; a separate “Export all” button points at the server-side handler URL.
See also: Bulk exports, CsvHandler, ExcelHandler.