Documentation

Styled Excel and PDF export

Three of the ten export formats need the Enterprise package: excel-list, excel-pivot and pdf. The other seven — CSV, JSON in three shapes, XML, print and clipboard — are free.

Everything structural is in the free core: flattening rows, building merged headers, resolving values, evaluating conditional-format rules. What Enterprise adds is the writing — ExcelJS and jsPDF, plus a streaming fallback for large sheets.

Turning it on

Importing anything from the Enterprise package registers the exporter. There is no configuration:

import { EnterprisePivotGrid } from '@kanunilabs/pivotgrid-react-enterprise';

The footer's download menu then enables the three paid entries. From code:

const ref = useRef<PivotGridRef<Sale>>(null);

ref.current?.exportData('excel-pivot', {
  fileName: 'Q4-revenue',
  applyFilters: true,
  expandAll: false,
  locale: 'tr-TR',
});

exportData returns a promise, so you can await it and catch a refusal:

try {
  await ref.current?.exportData('excel-pivot', { fileName: 'Q4' });
} catch (err) {
  // A Community grid refuses the three paid formats. See below.
}
OptionDefaultRead by the exporter
fileName'PivotExport'yes — the extension is appended
locale'tr-TR'pivot only; the flat list ignores it
applyFilters—yes
expandAll—yes
signal—only at chunk boundaries
onProgress—plumbed, never wired to any UI

ExportFormat and ExportOptions come from @kanunilabs/pivotgrid-core, not from the React package.

What this does not do

Size silently changes the file

excel-list past 100,000 rows stops producing a real .xlsx and starts producing SpreadsheetML with an .xls extension. Same menu item, same name, different file — and in that format every formatted number is written as a string, which Excel will not sum.

The pivot equivalent switches at 150,000 materialised cells and additionally drops conditional formatting, outline levels, frozen panes and column widths.

There is no warning at either threshold.

The file will not match the screen

Absent from every export path:

  • cellTemplate output — the exporter writes the underlying value
  • theme colours
  • vertical header merges
  • dataFieldPosition: 'rows', which the grid honours and the exporters ignore
  • localized total labels — the screen says "Genel Toplam", the file says "Grand Total". Nothing in the export is translated, although the translations exist.
  • conditional rules other than expression
  • when several conditional rules match a cell, the screen merges them all; the export applies the first

Progress and cancellation are not reachable from the UI

The footer menu passes neither signal nor onProgress — both are fully plumbed and wired to nothing. You can only use them through your own ref.

Even then, cancellation is coarse: the signal is polled at chunk boundaries and not during the three most expensive calls, and aborting discards all work.

PDF

A wide pivot gets one accommodation: landscape orientation. No page breaking by column, no scaling, no per-column widths.

No font is registered, so non-ASCII text is at risk — worth checking with Turkish characters before you rely on it, given the default export locale is tr-TR.

Community refuses, and says so

A Community grid asked for one of the three paid formats gets a rejected promise naming the format and the package that provides it. The refusal happens before the exporting event, so nothing is left waiting on it, and the rejection is routed to your onError handler — or to console.error if you have none.

Until this shipped it was a console.warn and a resolved promise, fired after onExporting — so a spinner started on that event span forever with a clean console.

If your application registers its own exporter under one of those format ids, yours wins: the gate looks for a custom exporter first and steps aside.

It is an edition gate, not a licence gate

An unlicensed Enterprise build still exports — watermarked, not crippled. That is deliberate and matches DataGrid: a dead feature cannot be evaluated before purchase.

What the gate closes is the accidental path. The exporter registers itself into a module-level slot when the Enterprise package is imported, and that slot cannot tell which grid is asking — so one Enterprise import anywhere used to enable styled export for every grid in the bundle, Community ones included. The controller can tell, so the check lives there.

It is not DRM. exportPivotData, PivotExportService and getAdvancedExporter are public exports of the free package, so deliberate code can still reach the exporter. Narrowing that is a breaking change and belongs in a major version.