---
product: "AG Grid"
title: "PDF Export - Extra Content"
description: "PDF Export can add document headings, page headers and footers, cover pages, and content before, after, or within the exported table."
enterprise: true
framework: javascript
version: "36.2.0"
related:
    - title: "Styles"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-styles/"
    - title: "Languages"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-languages/"
    - title: "Customising Content"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-customising-content/"
    - title: "Images"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-images/"
    - title: "Watermarks"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-watermarks/"
    - title: "Rows"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-rows/"
    - title: "Columns"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-columns/"
    - title: "Hyperlinks"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-hyperlinks/"
    - title: "Master Detail"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-master-detail/"
    - title: "Page Setup"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-page-setup/"
    - title: "API Reference"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-api/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# PDF Export - Extra Content

PDF Export can add document headings, page headers and footers, cover pages, and content before, after, or within the exported table.

## Document Headings

Use `documentTitle` to set the PDF metadata title and render a visible title above the table. Use `documentTitleStyle` to configure its font, colour, border, padding, margin, alignment, wrapping, line height, line limit, and overflow behaviour.

#### Document Title

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  PdfExportModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  ClientSideRowModelModule,
  PdfExportModule,
  ColumnMenuModule,
  ContextMenuModule,
]);

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: [
    {
      headerName: "Group A",
      children: [
        { field: "athlete", minWidth: 200 },
        { field: "country", minWidth: 200 },
      ],
    },
    {
      headerName: "Group B",
      children: [
        { field: "sport", minWidth: 150 },
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ],
  defaultColDef: {
    filter: true,
    minWidth: 100,
    flex: 1,
  },
  defaultPdfExportParams: {
    documentTitle: "Quarterly Results",
    documentTitleStyle: {
      fontSize: 16,
      padding: 6,
      margin: { bottom: 10 },
      backgroundColor: "#f3f6fb",
      borderColor: "#c3d4ea",
      borderWidth: 1,
      color: "#123a5a",
      alignment: "center",
    },
  },
};

function onBtExport() {
  gridApi!.exportDataAsPdf();
}

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
  .then((response) => response.json())
  .then(function (data) {
    gridApi!.setGridOption("rowData", data);
  });

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: Document Title](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-document-title/typescript/)

### Subtitle

Use `documentSubtitle` to render a subtitle below the title. It uses a smaller default font and can be styled independently with `documentSubtitleStyle`.

```js
const gridOptions = {
    documentTitle: 'Quarterly Results',
    documentSubtitle: 'Prepared for the board',

    // other grid options ...
}
```

#### Document Subtitle

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { ContextMenuModule, PdfExportModule } from "ag-grid-enterprise";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  PdfExportModule,
  ContextMenuModule,
]);

interface ReportRow {
  department: string;
  owner: string;
  result: number;
}

let gridApi: GridApi<ReportRow>;

const gridOptions: GridOptions<ReportRow> = {
  columnDefs: [
    { field: "department", flex: 1 },
    { field: "owner", flex: 1 },
    { field: "result", headerName: "Result (%)", flex: 1 },
  ],
  rowData: [
    { department: "Engineering", owner: "Maya Singh", result: 94 },
    { department: "Operations", owner: "Daniel Price", result: 88 },
    { department: "Sales", owner: "Sofia Costa", result: 91 },
    { department: "Support", owner: "Noah Williams", result: 96 },
  ],
  defaultPdfExportParams: {
    documentTitle: "Quarterly Results",
    documentSubtitle: "Prepared for the board",
    documentSubtitleStyle: {
      color: "#52606d",
      fontSize: 12,
    },
  },
};

function onBtExport() {
  gridApi.exportDataAsPdf();
}

gridApi = createGrid(
  document.querySelector<HTMLElement>("#myGrid")!,
  gridOptions,
);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: Document Subtitle](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-document-subtitle/typescript/)

## Page Headers And Footers

Use `headerFooterConfig` to add content to the left, centre, or right of each page header and footer. The `all` rule applies by default, while `first` and `even` replace it on the corresponding pages.

Each header or footer accepts up to three entries. When `position` is omitted, entries are positioned left, centre, and right in array order.

Each position uses one third of the printable page width. Header and footer text remains on one line and is truncated with an ellipsis when it exceeds that space. The required vertical space is reserved before the table is paginated.

### Page Headers

```js
const gridOptions = {
    headerFooterConfig: {
        all: {
            header: [{ value: 'Quarterly Results', position: 'Center' }],
        },
        first: {
            header: [{ value: 'Confidential Report', position: 'Center' }],
        },
    },

    // other grid options ...
}
```

#### Page Headers

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { ContextMenuModule, PdfExportModule } from "ag-grid-enterprise";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  PdfExportModule,
  ContextMenuModule,
]);

interface ReportRow {
  item: string;
  owner: string;
  status: string;
}

let gridApi: GridApi<ReportRow>;

const rowData: ReportRow[] = Array.from({ length: 60 }, (_, index) => ({
  item: `Work item ${index + 1}`,
  owner: ["Amelia", "Mateo", "Hana"][index % 3],
  status: index % 4 === 0 ? "In review" : "Complete",
}));

const gridOptions: GridOptions<ReportRow> = {
  columnDefs: [
    { field: "item", flex: 1 },
    { field: "owner", flex: 1 },
    { field: "status", flex: 1 },
  ],
  rowData,
  defaultPdfExportParams: {
    page: {
      orientation: "portrait",
    },
    headerFooterConfig: {
      all: {
        header: [
          {
            value: "Quarterly Results",
            position: "Center",
            style: { color: "#123a5a", fontWeight: "bold" },
          },
        ],
      },
      first: {
        header: [
          {
            value: "Confidential Report",
            position: "Center",
            style: { color: "#8b1d1d", fontWeight: "bold" },
          },
        ],
      },
    },
  },
};

function onBtExport() {
  gridApi.exportDataAsPdf();
}

gridApi = createGrid(
  document.querySelector<HTMLElement>("#myGrid")!,
  gridOptions,
);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: Page Headers](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-page-headers/typescript/)

### Page Footers

Header and footer values support the following placeholders:

- `&[Page]`: current page number.
- `&[Pages]`: total number of pages.
- `&[Date]`: date when the PDF export started.
- `&[Time]`: time when the PDF export started.

Date and time are captured once per export and formatted using the export `language`, when provided.

```js
const gridOptions = {
    headerFooterConfig: {
        all: {
            footer: [
                { value: '&[Date]', position: 'Left' },
                { value: 'Page &[Page] of &[Pages]', position: 'Center' },
                { value: '&[Time]', position: 'Right' },
            ],
        },
    },

    // other grid options ...
}
```

#### Page Footers

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { ContextMenuModule, PdfExportModule } from "ag-grid-enterprise";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  PdfExportModule,
  ContextMenuModule,
]);

interface ReportRow {
  item: string;
  owner: string;
  status: string;
}

let gridApi: GridApi<ReportRow>;

const rowData: ReportRow[] = Array.from({ length: 60 }, (_, index) => ({
  item: `Work item ${index + 1}`,
  owner: ["Amelia", "Mateo", "Hana"][index % 3],
  status: index % 4 === 0 ? "In review" : "Complete",
}));

const gridOptions: GridOptions<ReportRow> = {
  columnDefs: [
    { field: "item", flex: 1 },
    { field: "owner", flex: 1 },
    { field: "status", flex: 1 },
  ],
  rowData,
  defaultPdfExportParams: {
    page: {
      orientation: "portrait",
    },
    headerFooterConfig: {
      all: {
        footer: [
          { value: "&[Date]", position: "Left", style: { color: "#52606d" } },
          {
            value: "Page &[Page] of &[Pages]",
            position: "Center",
            style: { fontWeight: "bold" },
          },
          { value: "&[Time]", position: "Right", style: { color: "#52606d" } },
        ],
      },
    },
  },
};

function onBtExport() {
  gridApi.exportDataAsPdf();
}

gridApi = createGrid(
  document.querySelector<HTMLElement>("#myGrid")!,
  gridOptions,
);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: Page Footers](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-page-footers/typescript/)

## Cover Page

Set `coverPage=true` to place the document title and subtitle on the first page and begin the exported grid on the following page. Page header and footer rules still apply, so `headerFooterConfig.first` can customise the cover page.

```js
const gridOptions = {
    coverPage: true,
    documentTitle: 'Annual Performance Report',
    documentSubtitle: 'Financial year 2026',

    // other grid options ...
}
```

#### PDF Cover Page

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import { ContextMenuModule, PdfExportModule } from "ag-grid-enterprise";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  PdfExportModule,
  ContextMenuModule,
]);

interface ReportRow {
  department: string;
  owner: string;
  result: number;
}

let gridApi: GridApi<ReportRow>;

const gridOptions: GridOptions<ReportRow> = {
  columnDefs: [
    { field: "department", flex: 1 },
    { field: "owner", flex: 1 },
    { field: "result", headerName: "Result (%)", flex: 1 },
  ],
  rowData: [
    { department: "Engineering", owner: "Maya Singh", result: 94 },
    { department: "Operations", owner: "Daniel Price", result: 88 },
    { department: "Sales", owner: "Sofia Costa", result: 91 },
    { department: "Support", owner: "Noah Williams", result: 96 },
  ],
  defaultPdfExportParams: {
    coverPage: true,
    documentTitle: "Annual Performance Report",
    documentTitleStyle: {
      fontSize: 24,
      margin: { top: 120, bottom: 8 },
      borderColor: "#123a5a",
      borderWidth: 1,
      color: "#123a5a",
    },
    documentSubtitle: "Financial year 2026",
    documentSubtitleStyle: {
      color: "#52606d",
      fontSize: 14,
    },
    headerFooterConfig: {
      all: {
        footer: [{ value: "Page &[Page] of &[Pages]", position: "Center" }],
      },
      first: {
        footer: [
          {
            value: "Confidential",
            position: "Center",
            style: { color: "#8b1d1d" },
          },
        ],
      },
    },
  },
};

function onBtExport() {
  gridApi.exportDataAsPdf();
}

gridApi = createGrid(
  document.querySelector<HTMLElement>("#myGrid")!,
  gridOptions,
);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: PDF Cover Page](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-cover-page/typescript/)

## Additional Content

Use `prependContent`, `appendContent`, or `getCustomContentBelowRow` to add content that is not displayed in the grid. Strings create full-width rows. Use `PdfCell[][]` for explicit spans and styling.

See [PDF Export - Master Detail](https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/pdf-export-master-detail/) for an example that uses `getCustomContentBelowRow` to include detail data below each master row.

#### Custom Content

```ts
import {
  ClientSideRowModelModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  ProcessRowGroupForExportParams,
  TextFilterModule,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  PdfExportModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

ModuleRegistry.registerModules([
  TextFilterModule,
  NumberFilterModule,
  ClientSideRowModelModule,
  PdfExportModule,
  ColumnMenuModule,
  ContextMenuModule,
]);

let gridApi: GridApi<IOlympicData>;

const gridOptions: GridOptions<IOlympicData> = {
  columnDefs: [
    { field: "athlete", minWidth: 200 },
    { field: "country", minWidth: 160 },
    { field: "sport", minWidth: 140 },
    { field: "total" },
  ],
  defaultColDef: {
    filter: true,
    minWidth: 100,
    flex: 1,
  },
  defaultPdfExportParams: {
    getCustomContentBelowRow: (params: ProcessRowGroupForExportParams) => {
      const rowIndex = params.node.rowIndex ?? 0;
      if ((rowIndex + 1) % 5 !== 0) {
        return;
      }

      return [
        [
          {
            data: { value: "Section break" },
            mergeAcross: 3,
            style: {
              backgroundColor: "#fff4cc",
              borderColor: "#f0c36d",
              borderWidth: 1,
              color: "#7a5400",
              padding: 6,
              alignment: "center",
            },
          },
        ],
      ];
    },
  },
};

function onBtExport() {
  gridApi!.exportDataAsPdf();
}

const gridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(gridDiv, gridOptions);

fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
  .then((response) => response.json())
  .then(function (data) {
    gridApi!.setGridOption("rowData", data);
  });

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).onBtExport = onBtExport;
}
```

[Live example: Custom Content](https://www.ag-grid.com/archive/36.2.0/examples/pdf-export-extra-content/pdf-custom-content/typescript/)

## API

### Export Options

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `documentTitle` | `string` |  |  |  |
| `documentTitleStyle` | `PdfDocumentHeadingStyle` |  |  |  |
| `documentSubtitle` | `string` |  |  |  |
| `documentSubtitleStyle` | `PdfDocumentHeadingStyle` |  |  |  |
| `coverPage` | `boolean` |  |  |  |
| `headerFooterConfig` | `PdfHeaderFooterConfig` |  |  |  |
| `prependContent` | `PdfCustomContent` |  |  |  |
| `appendContent` | `PdfCustomContent` |  |  |  |
| `getCustomContentBelowRow` | `Function` |  |  |  |

### PdfDocumentHeadingStyle

Properties available on the `PdfDocumentHeadingStyle` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `margin` | `number \| PdfMargin` |  |  |  |
| `backgroundColor` | `string` |  |  |  |
| `borderColor` | `string` |  |  |  |
| `borderWidth` | `number` |  |  |  |
| `padding` | `number \| PdfMargin` |  |  |  |
| `alignment` | `PdfTextAlignment` |  |  |  |
| `wrapText` | `boolean` |  |  |  |
| `preserveLineBreaks` | `boolean` |  |  |  |
| `preserveSpaces` | `boolean` |  |  |  |
| `maxLines` | `number` |  |  |  |
| `overflow` | `PdfTextOverflow` |  |  |  |
| `fontSize` | `number` |  |  |  |
| `fontFamily` | `PdfFontFamily` |  |  |  |
| `fontWeight` | `PdfFontWeight` |  |  |  |
| `fontStyle` | `PdfFontStyle` |  |  |  |
| `direction` | `PdfTextDirection` |  |  |  |
| `language` | `string` |  |  |  |
| `color` | `string` |  |  |  |
| `lineHeight` | `number` |  |  |  |

### PdfHeaderFooterConfig

Properties available on the `PdfHeaderFooterConfig` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `all` | `PdfHeaderFooter` |  |  |  |
| `first` | `PdfHeaderFooter` |  |  |  |
| `even` | `PdfHeaderFooter` |  |  |  |

### PdfHeaderFooter

Properties available on the `PdfHeaderFooter` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `header` | `PdfHeaderFooterContent[]` |  |  |  |
| `footer` | `PdfHeaderFooterContent[]` |  |  |  |

### PdfHeaderFooterTextContent

Properties available on the `PdfHeaderFooterTextContent` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` |  |  |  |
| `image` | `PdfImage` |  |  |  |
| `position` | `'Left' \| 'Center' \| 'Right'` |  |  |  |
| `style` | `PdfTextStyle` |  |  |  |

### PdfHeaderFooterImageContent

Properties available on the `PdfHeaderFooterImageContent` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` |  |  |  |
| `image` | `PdfImage` |  |  |  |
| `position` | `'Left' \| 'Center' \| 'Right'` |  |  |  |
| `style` | `PdfTextStyle` |  |  |  |

### PdfTextStyle

Properties available on the `PdfTextStyle` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `fontSize` | `number` |  |  |  |
| `fontFamily` | `PdfFontFamily` |  |  |  |
| `fontWeight` | `PdfFontWeight` |  |  |  |
| `fontStyle` | `PdfFontStyle` |  |  |  |
| `direction` | `PdfTextDirection` |  |  |  |
| `language` | `string` |  |  |  |
| `color` | `string` |  |  |  |
| `lineHeight` | `number` |  |  |  |

### PdfCell

Properties available on the `PdfCell` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | `PdfCellData` |  |  |  |
| `mergeAcross` | `number` |  |  |  |
| `style` | `PdfCellStyle` |  |  |  |

### PdfCellData

Properties available on the `PdfCellData` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string \| null` |  |  |  |
| `hyperlink` | `string` |  |  |  |
| `image` | `PdfImage` |  |  |  |
