# Export Providers
URL: https://pro.rv-grid.com/guides/excel-export/providers/
Source: src/content/docs/guides/excel-export/providers.mdx
Description: Choose the default XLSX provider, optional adapters, or a custom Excel export provider.
`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'`

## Default Provider

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

```ts
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`.

## Provider Options

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

```ts
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 option | Source |
| --- | --- |
| `columns` widths | Current grid column sizes |
| `stickyRowsCount` | Generated header row plus pinned-top rows |
| `stickyColumnsCount` | `colPinStart` columns |

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

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

## Grid-Level Provider

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

```ts
grid.exportExcel = {
  exportProvider: myProvider,
};
```

Override it for one export call:

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

## Optional ExcelJS Provider

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

```sh
pnpm add exceljs
```

```ts
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.

## Optional SheetJS Provider

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

```sh
pnpm add xlsx
```

```ts
import * as XLSX from 'xlsx';
import { createSheetJsExcelExportProvider } from '@revolist/revogrid-pro';

grid.exportExcel = {
  exportProvider: createSheetJsExcelExportProvider(XLSX),
};
```

The SheetJS adapter writes plain row objects from `context.rows`. It does not consume formatted `cellRows`, grouped header rows, or merge spans. Use ExcelJS or a custom provider when workbook formatting must be preserved.

## Workbook Module Adapter

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

```ts
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.

## Custom Provider

Any object that implements `ExcelExportProvider` can write the workbook:

```ts
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`.

## Provider Context Notes

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](/guides/excel-export/excel-import-export-libraries/).
