---
product: "AG Grid"
title: "Excel Export - Data Protection"
description: "Excel Export allows you to protect the exported worksheet so that users can only edit specific cells."
enterprise: true
framework: react
version: "36.2.0"
related:
    - title: "Styles"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-styles/"
    - title: "Formulas"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-formulas/"
    - title: "Extra Content"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-extra-content/"
    - title: "Notes"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-notes/"
    - title: "Customising Content"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-customising-content/"
    - title: "Images"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-images/"
    - title: "Excel Tables"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-tables/"
    - title: "Multiple Sheets"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-multiple-sheets/"
    - title: "Rows"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-rows/"
    - title: "Columns"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-columns/"
    - title: "Freezing Content"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-freeze/"
    - title: "Data Types"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-data-types/"
    - title: "Hyperlinks"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-hyperlinks/"
    - title: "Master Detail"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-master-detail/"
    - title: "Page Setup"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-page-setup/"
    - title: "API Reference"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-api/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Excel Export - Data Protection

Excel Export allows you to protect the exported worksheet so that users can only edit specific cells.

## Data Protection

Excel has two layers of protection:

1. **Cell Protection** controls whether a cell is *locked* and whether a formula is *hidden* (`ExcelStyle.protection`).
2. **Worksheet Protection** enables enforcement of the locked/unlocked cell states (`ExcelExportParams.protectSheet`).

> **Note**
>
> Cell locking only takes effect when the worksheet is protected. If you lock cells but do not enable worksheet protection, all cells will remain editable in Excel.

Enable worksheet protection by setting `protectSheet` in the [Excel Export Params](https://www.ag-grid.com/archive/36.2.0/react-data-grid/excel-export-api/#excelexportparams) (or in `defaultExcelExportParams`):

```jsx
const defaultExcelExportParams = useMemo(() => { 
	return {
        protectSheet: true
    };
}, []);

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

#### Excel Export - Data Protection (Default)

```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,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  TextFilterModule,
  NumberFilterModule,
  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 [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", minWidth: 200 },
    { field: "country", minWidth: 180 },
    { field: "sport", minWidth: 150 },
    { field: "gold", width: 100 },
    { field: "silver", width: 100 },
    { field: "bronze", width: 100 },
    { field: "total", width: 100 },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      filter: true,
      minWidth: 100,
      flex: 1,
    };
  }, []);
  const defaultExcelExportParams = useMemo<ExcelExportParams>(() => {
    return {
      protectSheet: true,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/small-olympic-winners.json",
  );

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

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div className="controls">
            <button
              onClick={onBtExport}
              style={{ marginBottom: "5px", fontWeight: "bold" }}
            >
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
                defaultExcelExportParams={defaultExcelExportParams}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Excel Export - Data Protection (Default)](https://www.ag-grid.com/archive/36.2.0/examples/excel-export-data-protection/excel-export-data-protection-default/reactFunctionalTs/)

## Worksheet Custom Protection

To allow specific actions, or to require a password to unprotect the sheet, provide an `ExcelSheetProtection` config object:

```jsx
const defaultExcelExportParams = useMemo(() => { 
	return {
        protectSheet: {
            password: 'secret',
            autoFilter: true,
            formatCells: true
        }
    };
}, []);

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

#### Excel Export - Data Protection (Custom Sheet Protection)

```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,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

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

const isChecked = (selector: string): boolean =>
  document.querySelector<HTMLInputElement>(selector)?.checked ?? false;

const getInputValue = (selector: string): string =>
  document.querySelector<HTMLInputElement>(selector)?.value ?? "";

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", minWidth: 200 },
    { field: "country", minWidth: 180 },
    { field: "sport", minWidth: 150 },
    { field: "gold", width: 100 },
    { field: "silver", width: 100 },
    { field: "bronze", width: 100 },
    { field: "total", width: 100 },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      filter: true,
      minWidth: 100,
      flex: 1,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/small-olympic-winners.json",
  );

  const onBtExport = useCallback(() => {
    const password = getInputValue("#worksheetPassword").trim() || undefined;
    const autoFilter = isChecked("#allowAutoFilter");
    const formatCells = isChecked("#allowFormatCells");
    gridRef.current!.api.exportDataAsExcel({
      protectSheet: {
        password,
        autoFilter,
        formatCells,
      },
    });
  }, [isChecked]);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div className="controls">
            <label className="option">
              Worksheet password (optional):
              <input type="text" id="worksheetPassword" defaultValue="secret" />
            </label>
            <label className="option">
              <input type="checkbox" id="allowAutoFilter" />
              Allow filtering (autoFilter)
            </label>
            <label className="option">
              <input type="checkbox" id="allowFormatCells" />
              Allow formatting cells (formatCells)
            </label>
            <button
              onClick={onBtExport}
              style={{ marginBottom: "5px", fontWeight: "bold" }}
            >
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Excel Export - Data Protection (Custom Sheet Protection)](https://www.ag-grid.com/archive/36.2.0/examples/excel-export-data-protection/excel-export-data-protection-custom/reactFunctionalTs/)

> **Note**
>
> Excel uses an obfuscation algorithm for worksheet protection passwords. It should not be treated as strong security.

## Unlocking Cells

When worksheet protection is enabled, all exported cells are locked by default. To unlock specific cells or columns, configure an Excel style with `protection.protected = false` and apply that style via `cellClass` / `cellClassRules`:

```jsx
const [columnDefs, setColumnDefs] = useState([
    { field: 'athlete', cellClass: 'unlocked' },
    { field: 'country', cellClass: 'unlocked' }
]);
const excelStyles = useMemo(() => { 
	return [
        {
            id: 'unlocked',
            protection: { protected: false, hideFormula: false }
        }
    ];
}, []);
const defaultExcelExportParams = useMemo(() => { 
	return {
        protectSheet: true
    };
}, []);

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

#### Excel Export - Data Protection (Unlocking Cells)

```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,
  CsvExportModule,
  ExcelExportParams,
  ExcelStyle,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  TextEditorModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  CellStyleModule,
  TextFilterModule,
  TextEditorModule,
  NumberFilterModule,
  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 excelStyles = useMemo<ExcelStyle[]>(() => {
    return [
      {
        id: "unlocked",
        interior: {
          color: "#C6EFCE",
          pattern: "Solid",
        },
        protection: {
          protected: false,
          hideFormula: false,
        },
      },
    ];
  }, []);
  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Editable (Unlocked)",
      children: [
        {
          field: "athlete",
          minWidth: 200,
          cellClass: "unlocked",
          editable: true,
        },
        {
          field: "country",
          minWidth: 200,
          cellClass: "unlocked",
          editable: true,
        },
      ],
    },
    {
      headerName: "Read Only (Locked)",
      children: [
        { field: "sport", minWidth: 150 },
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      filter: true,
      minWidth: 100,
      flex: 1,
    };
  }, []);
  const defaultExcelExportParams = useMemo<ExcelExportParams>(() => {
    return {
      protectSheet: true,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/small-olympic-winners.json",
  );

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

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="container">
          <div className="controls">
            <button
              onClick={onBtExport}
              style={{ marginBottom: "5px", fontWeight: "bold" }}
            >
              Export to Excel
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                excelStyles={excelStyles}
                columnDefs={columnDefs}
                defaultColDef={defaultColDef}
                defaultExcelExportParams={defaultExcelExportParams}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Excel Export - Data Protection (Unlocking Cells)](https://www.ag-grid.com/archive/36.2.0/examples/excel-export-data-protection/excel-export-unlocking-cells/reactFunctionalTs/)

## Interfaces

### ExcelExportParams

```ts
interface ExcelExportParams {
    // ...
    protectSheet?: boolean | ExcelSheetProtection;
}
```

### ExcelSheetProtection

Properties available on the `ExcelSheetProtection` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `autoFilter` | `boolean` |  |  |  |
| `deleteColumns` | `boolean` |  |  |  |
| `deleteRows` | `boolean` |  |  |  |
| `formatCells` | `boolean` |  |  |  |
| `formatColumns` | `boolean` |  |  |  |
| `formatRows` | `boolean` |  |  |  |
| `insertColumns` | `boolean` |  |  |  |
| `insertHyperlinks` | `boolean` |  |  |  |
| `insertRows` | `boolean` |  |  |  |
| `pivotTables` | `boolean` |  |  |  |
| `selectLockedCells` | `boolean` |  |  |  |
| `selectUnlockedCells` | `boolean` |  |  |  |
| `password` | `string` |  |  |  |

### ExcelStyle

```ts
interface ExcelStyle {
    // ...
    protection?: ExcelProtection;
}
```

### ExcelProtection

Properties available on the `ExcelProtection` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `protected` | `boolean` |  |  |  |
| `hideFormula` | `boolean` |  |  |  |
