---
title: "Excel Export - Images"
enterprise: true
framework: react
version: "36.1.0"
---

# Excel Export - Images

Excel Export allows including images in the Excel export file. For example, you can add your company logo to the top or bottom of the exported Excel spreadsheet, or export any images you're displaying inside grid cells.

## Exporting Images

You can export an image for any grid cell using the addImageToCell callback in the [export parameters](https://www.ag-grid.com/react-data-grid/excel-export-api/#excelexportparams) shown below:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `addImageToCell` | `Function` |  |  | Use to export an image for the gridCell in question. |

```jsx
const defaultExcelExportParams = useMemo(() => { 
	return {
        addImageToCell: (rowIndex, column, value) => {
            if (rowIndex === 1 && column.colId === 'athlete') {
                const myCompanyLogo = getBase64Image('logo.png');
                return {
                    image: {
                        id: 'company_logo',
                        base64: myCompanyLogo,
                        imageType: 'png',
                        fitCell: true
                    }
                };
            }
        }
    };
}, []);

<AgGridReact defaultExcelExportParams={defaultExcelExportParams} />
```

It's important to note that images can only be exported as `base64` strings, and the image format must be either `PNG`, `GIF` or `JPG`. You can convert your images to a `base64` string, using third party tools, or using the code in our examples on this page.

> **Note**
>
> Every image is required to have an `id`. This way, if you're exporting the same image multiple times as part of the same export operation, the `id` will be used to access the image data, so the image file is imported only once.

> **Warning**
>
> At the moment, it's only possible to export one image per cell.

## Cells with Images

The example below includes a [Custom Cell Renderer](https://www.ag-grid.com/react-data-grid/component-cell-renderer/) and uses the `addImageToCell` callback to convert the cell value into a `base64` image.

Note the following:

- The image gets a margin within the cell because of the `offsetX` and `offsetY` properties in the `ExcelImage`.

#### Excel Export - Cells with Images

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ExcelExportParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { createBase64FlagsFromResponse } from "./imageUtils";
import { FlagContext } from "./interfaces";
import CountryCellRenderer from "./countryCellRenderer.tsx";
import { IOlympicData } from "./interfaces";

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

const modules = [
  ClientSideRowModelModule,
  ExcelExportModule,
  ColumnMenuModule,
  ContextMenuModule,
];

const countryCodes: any = {};

const base64flags: any = {};

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<IOlympicData[]>();
  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    {
      field: "country",
      headerName: " ",
      minWidth: 70,
      width: 70,
      maxWidth: 70,
      cellRenderer: CountryCellRenderer,
      cellRendererParams: {
        base64flags: base64flags,
        countryCodes: countryCodes,
      },
    },
    { field: "athlete" },
    { field: "age" },
    { field: "year" },
    { field: "date" },
    { field: "sport" },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      width: 150,
    };
  }, []);
  const defaultExcelExportParams = useMemo<ExcelExportParams>(() => {
    return {
      addImageToCell: (rowIndex, col, value) => {
        if (col.getColId() !== "country") {
          return;
        }
        const countryCode = countryCodes[value];
        return {
          image: {
            id: countryCode,
            base64: base64flags[countryCode],
            imageType: "png",
            width: 20,
            height: 11,
            position: {
              offsetX: 30,
              offsetY: 5.5,
            },
          },
        };
      },
    };
  }, []);
  const context = useMemo(() => {
    return {
      base64flags: base64flags,
      countryCodes: countryCodes,
    } as FlagContext;
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
      .then((data) =>
        createBase64FlagsFromResponse(data, countryCodes, base64flags),
      )
      .then((data) => setRowData(data));
  }, []);

  const onBtExport = useCallback(() => {
    gridRef.current!.api.exportDataAsExcel();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div>
            <button className="export" onClick={onBtExport}>
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={rowData}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
                defaultExcelExportParams={defaultExcelExportParams}
                context={context}
                onGridReady={onGridReady}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Excel Export - Cells with Images](https://www.ag-grid.com/examples/excel-export-images/excel-export-cells-with-images/reactFunctionalTs)

## Cells with Images and Text

This example has a [Custom Cell Renderer](https://www.ag-grid.com/react-data-grid/component-cell-renderer/) showing an image together with text, and uses the `addImageToCell` to convert the cell value into a `base64` image.

Note the following:

- The image gets a margin within the cell because of the `offsetX` and `offsetY` properties in the `ExcelImage`.
- This example returns the image and a value. The value is rendered within the same cell as the image.
- [Excel Styles](https://www.ag-grid.com/react-data-grid/excel-export-styles/) are used to indent the text and vertically align it with the image.

#### Excel Export - Cells with Images and Text

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  CellStyleModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ExcelExportParams,
  ExcelStyle,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ICellRendererParams,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { createBase64FlagsFromResponse } from "./imageUtils";
import { FlagContext } from "./interfaces";
import CountryCellRenderer from "./countryCellRenderer.tsx";
import { IOlympicData } from "./interfaces";

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

const modules = [
  CellStyleModule,
  ClientSideRowModelModule,
  ExcelExportModule,
  ColumnMenuModule,
  ContextMenuModule,
];

const countryCodes: any = {};

const base64flags: any = {};

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<IOlympicData[]>();
  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", width: 200 },
    {
      field: "country",
      cellClass: "countryCell",
      cellRenderer: CountryCellRenderer,
    },
    { field: "age" },
    { field: "year" },
    { field: "date" },
    { field: "sport" },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      width: 150,
    };
  }, []);
  const excelStyles = useMemo<ExcelStyle[]>(() => {
    return [
      {
        id: "countryCell",
        alignment: {
          vertical: "Center",
          indent: 4,
        },
      },
    ];
  }, []);
  const defaultExcelExportParams = useMemo<ExcelExportParams>(() => {
    return {
      addImageToCell: (rowIndex, col, value) => {
        if (col.getColId() !== "country") {
          return;
        }
        const countryCode = countryCodes[value];
        return {
          image: {
            id: countryCode,
            base64: base64flags[countryCode],
            imageType: "png",
            width: 20,
            height: 11,
            position: {
              offsetX: 10,
              offsetY: 5.5,
            },
          },
          value,
        };
      },
    };
  }, []);
  const context = useMemo(() => {
    return {
      base64flags: base64flags,
      countryCodes: countryCodes,
    } as FlagContext;
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
      .then((data) =>
        createBase64FlagsFromResponse(data, countryCodes, base64flags),
      )
      .then((data) => setRowData(data));
  }, []);

  const onBtExport = useCallback(() => {
    gridRef.current!.api.exportDataAsExcel();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div>
            <button className="export" onClick={onBtExport}>
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={rowData}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
                excelStyles={excelStyles}
                defaultExcelExportParams={defaultExcelExportParams}
                context={context}
                onGridReady={onGridReady}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Excel Export - Cells with Images and Text](https://www.ag-grid.com/examples/excel-export-images/excel-export-cells-with-images-text/reactFunctionalTs)

## Prepend Images

This example uses the [prepend content](https://www.ag-grid.com/react-data-grid/excel-export-extra-content/#prepending-and-appending-custom-content) to add a custom logo to the export.

Note the following:

- The first row has a larger height as set in the `rowHeight` callback.
- The custom content added using `prependContent` spans across two columns.

> **Note**
>
> Even if an ExcelCell object that merges multiple cells across is created, the `ExcelImage` still needs be informed of how many columns it will be spanning. This is done by passing `position: { colSpan: number }` to the `ExcelImage`.

#### Excel Export - Prepend Images

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  CsvExportModule,
  ExcelExportParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { logos } from "./imageUtils";
import { IOlympicData } from "./interfaces";

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

const modules = [
  ClientSideRowModelModule,
  CsvExportModule,
  ExcelExportModule,
  ColumnMenuModule,
  ContextMenuModule,
];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<IOlympicData[]>();
  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete" },
    { field: "country" },
    { field: "age" },
    { field: "year" },
    { field: "date" },
    { field: "sport" },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      width: 150,
    };
  }, []);
  const defaultExcelExportParams = useMemo<ExcelExportParams>(() => {
    return {
      prependContent: [
        {
          cells: [
            {
              data: {
                type: "String",
                value: logos.AgGrid, // see imageUtils
              },
              mergeAcross: 1,
            },
          ],
        },
      ],
      rowHeight: (params) => (params.rowIndex === 1 ? 82 : 20),
      addImageToCell: (rowIndex, col, value) => {
        if (rowIndex !== 1 || col.getColId() !== "athlete") {
          return;
        }
        return {
          image: {
            id: "logo",
            base64: value,
            imageType: "png",
            width: 295,
            height: 100,
            position: {
              colSpan: 2,
            },
          },
        };
      },
    };
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
      .then((response) => response.json())
      .then((data) => setRowData(data));
  }, []);

  const onBtExport = useCallback(() => {
    gridRef.current!.api.exportDataAsExcel();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div>
            <button className="export" onClick={onBtExport}>
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={rowData}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
                defaultExcelExportParams={defaultExcelExportParams}
                onGridReady={onGridReady}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Excel Export - Prepend Images](https://www.ag-grid.com/examples/excel-export-images/excel-export-prepend-images/reactFunctionalTs)
