Skip to content

Export Providers

ExportExcelPlugin prepares one provider context, applies built-in feature transforms, applies custom exportTransformers, then passes the context to the selected provider.

Provider resolution is:

  1. plugin.export({ provider })
  2. grid.exportExcel.exportProvider
  3. bundled 'write-excel-file'

The bundled provider is backed by write-excel-file/browser and exports .xlsx only:

await excel.export({
workbookName: 'orders',
sheetName: 'Orders',
});

Extensionless workbook names receive .xlsx, so orders becomes orders.xlsx.

The default provider rejects incompatible workbook output clearly:

  • writingOptions.bookType must be xlsx.
  • workbookName must be extensionless or end in .xlsx.
  • Use an optional adapter or custom provider for formats such as .xlsb, .xls, .csv, or .ods.

providerOptions are forwarded to the selected provider. For the bundled provider, they are merged into the options passed to write-excel-file.

await excel.export({
workbookName: 'orders.xlsx',
providerOptions: {
fontFamily: 'Arial',
fontSize: 12,
hideGridLines: true,
zoomScale: 90,
},
});

By default, the export pipeline derives provider hints from the live grid:

Derived optionSource
columns widthsCurrent grid column sizes
stickyRowsCountGenerated header row plus pinned-top rows
stickyColumnsCountcolPinStart columns

Explicit providerOptions override derived values. Disable derivation for a single export with deriveGridOptions: false:

await excel.export({
deriveGridOptions: false,
providerOptions: {
stickyRowsCount: 0,
stickyColumnsCount: 2,
},
});

Use grid.exportExcel.exportProvider when one grid should consistently use the same workbook library:

grid.exportExcel = {
exportProvider: myProvider,
};

Override it for one export call:

await excel.export({
provider: anotherProvider,
workbookName: 'report.xlsx',
});

ExcelJS is not bundled. Install it in your app and pass the module object to the provider factory:

Terminal window
pnpm add exceljs
import ExcelJS from 'exceljs';
import { createExcelJsExcelExportProvider } from '@revolist/revogrid-pro';
grid.exportExcel = {
exportProvider: createExcelJsExcelExportProvider(ExcelJS),
};

The ExcelJS adapter consumes the formatted cellRows matrix, maps common cell formatting to ExcelJS styles, applies grid-derived widths and freeze panes, and writes/downloads the workbook through ExcelJS.

Use ExcelJS when export needs richer workbook styling, merge support, row heights, freeze panes, or library-specific worksheet setup.

SheetJS is not bundled. Install it in your app and pass the module object to the provider factory:

Terminal window
pnpm add xlsx
import * as XLSX from 'xlsx';
import { createSheetJsExcelExportProvider } from '@revolist/revogrid-pro';
grid.exportExcel = {
exportProvider: createSheetJsExcelExportProvider(XLSX),
};

Use createWorkbookModuleExcelExportProvider() for simple workbook-like modules that can create a worksheet from plain row objects:

import { createWorkbookModuleExcelExportProvider } from '@revolist/revogrid-pro';
grid.exportExcel = {
exportProvider: createWorkbookModuleExcelExportProvider({
createWorkbook,
createWorksheet,
appendWorksheet,
writeFile,
}),
};

Like the SheetJS adapter, the workbook-module adapter uses context.rows. Use a full custom provider when the library needs formatted cells, grouped headers, merge metadata, or custom workbook setup.

Any object that implements ExcelExportProvider can write the workbook:

import type { ExcelExportProvider } from '@revolist/revogrid-pro';
const myProvider: ExcelExportProvider = {
id: 'app-provider',
async export(context) {
await writeWorkbook({
fileName: context.workbookName,
sheetName: context.sheetName,
cells: context.cellRows,
metadata: context.exportMetadata,
});
},
};

Custom providers should use the prepared context instead of reading rendered DOM rows. Virtualized rows are already included in rows, sourceRows, and cellRows.

The export context is built from RevoGrid data stores first, with grid element sources as a compatibility fallback. This matters for virtualized grids: providers should not query rendered rows because offscreen records may not be mounted in the DOM.

Pinned row segments are preserved in sourceRows:

  • rowPinStart for pinned top rows
  • rgRow for body rows
  • rowPinEnd for pinned bottom rows

The prepared rows array keeps the same pinned-top, body, pinned-bottom order after formula evaluation. The formatted cellRows matrix adds generated header rows before those data rows.

For workbook providers:

  • Use cellRows when you need formatted values, column-level cell properties, grouped headers, formulas, or merge spans.
  • Use sourceRows when you need row-segment semantics, original models, or source indexes.
  • Use rows only for plain row-object export where formatting and merge metadata do not matter.

If a grid data store is not initialized yet, export falls back to the grid element source for that segment. Missing pinned sources are treated as empty arrays.

For broader library selection guidance, see Excel Import and Export Libraries.