> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/spreadsheet-editor/edit-mode.md).

# Spreadsheet Editor - Edit Mode

Apryse Spreadsheet Editor delivers Excel-like XLSX editing in the browser—part of the Web SDK Office suite. Programmatically edit using Spreadsheet Editor code samples.

{% hint style="info" %}
**Requirements**

*These packages are required to use these features in production. Trial keys have unlimited access to all features*

<a href="/web/get-started/readme.md" class="button primary">Web SDK</a><a href="https://apryse.com/capabilities#SpreadsheetEditor" class="button primary">Package: Spreadsheet Editor</a><a href="https://showcase.apryse.com/spreadsheet-editor" class="button primary">Live demo</a>
{% endhint %}

The Spreadsheet Editor is in edit mode by default. In edit mode, users can modify and interact with spreadsheets using familiar, grid-based interactions similar to Excel. Users can interact with cells, including:

* **Cell formatting:** Modify text size and color, fonts, border styles, cell colors, border colors, and text styling for bold, italics, underlining, and strikethrough.
* **Formula and function support:** Execute standard mathematical operations, statistical calculations, date/time functions, and other common formulas.
* **Dynamic data manipulation:** Easily add, edit, and delete rows and columns. Seamlessly cut, copy, and paste data.
* **Cell adjustments:** Merge cells and preserve formatting.
* **File support:** Open files in XLSX, XLS, and CSV formats. Export as XLSX or PDF.

Edit mode is ideal for tasks like data entry, adjusting cell styles, and organizing sheet content.

Users can click the dropdown on the **Mode** flyout in the upper-right corner of the Spreadsheet Editor UI to switch between **Viewing** and **Editing** mode.

For programmatic changes, you could, for example, build a reporting dashboard that imports sales data into a spreadsheet. After the data is loaded, the app programmatically applies formatting - bold headers, alternating row colors, and column width adjustments- improving readability without requiring users to manually style the sheet. You'd use the [CellRange constructor](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.CellRange.html) to create an instance, then apply styling with the `Sheet.setCellRangeStyle` API.

{% hint style="info" %}
Spreadsheet Editor must be purchased as an [add-on to your Web SDK subscription](https://apryse.com/capabilities).
{% endhint %}

![Screenshot of the Apryse SDK Spreadsheet Editor with labeled callouts highlighting UI features such as clipboard operations, a formula bar, cell fonts, cell styling, and sheet tabs.](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-7e92fdb2187150cf6221602049ec323bb6c5002b%2F51db0fafda7dc98b20a9a7b9d12be73a9152676e-1885x1069.png?alt=media)

See our [interactive Spreadsheet Editor demo](https://showcase.apryse.com/office-editor).

## Workbook

A workbook is the top-level container for all spreadsheet data. It includes multiple sheets and supports operations such as getting, creating, removing, or switching sheets. Users can interact with the workbook through the UI or programmatically using the Workbook [class](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html). The workbook instance can be retrieved with the `SpreadsheetEditorManager.getWorkbook` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#getWorkbook__anchor) shown in the following sample.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
  
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Get a sheet

The following code sample shows how to get a sheet with the 0-based index using the `Workbook.getSheetAt` [API ](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#getSheetAt__anchor)after the editor is initialized.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

A sheet can also be retrieved by its name using the `Workbook.getSheet` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#getSheet__anchor).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheet('Invoice');
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Create sheets

The following code sample creates a new sheet using the `Workbook.createSheet` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#createSheet__anchor) after the editor is initialized.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      workbook.createSheet('New Sheet');
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Remove sheets

The following code sample removes a sheet using the `Workbook.removeSheet` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#removeSheet__anchor).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();

    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      workbook.removeSheet('New Sheet');
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Set active sheet

The following code sample sets the last sheet of the workbook to be active using the `Workbook.setActiveSheet` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#setActiveSheet__anchor) and `Workbook.sheetCount` property.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      workbook.setActiveSheet(workbook.sheetCount - 1);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Sheets

Sheets are tabbed pages within a workbook, each with its own grid of cells, or rows of cells. They help organize data into separate sections, like months, categories, or teams. Only the active sheet is visible and editable at a time. Sheets can also be managed programmatically for dynamic workflows.

A sheet instance can be retrieved from a workbook instance using the `Workbook.getSheet` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#getSheet__anchor) or `Workbook.getSheetAt` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#getSheetAt__anchor).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();

    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheet('Sheet1');
      
      // Alternatively, using the zero-based index API, you
      // can retrieve the first sheet in a workbook.
      const firstSheet = workbook.getSheetAt(0);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Access rows

See the [Row documentation](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Row.html) for available APIs. The following code sample gets the first row from a sheet in a workbook.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
      let row = sheet.getRowAt(0);
      
      // Alternatively, you can chain the methods together.
      row = workbook.getSheetAt(0).getRowAt(0);
      console.log(row);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Add rows and columns

The following code sample shows how to add rows and columns to a sheet.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);

      const count = 5;
      const startIndex = 0;
      
      // Inserts 5 rows and columns at the
      // first row and column of a sheet.
      sheet.createRows(startIndex, count);
      sheet.createColumns(startIndex, count);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Remove rows and columns

The following code sample shows how to remove rows and columns from a sheet.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
      
      const count = 5;
      const startIndex = 0;
      
      // Removes 5 rows and columns starting
      // from the top-left (0 index) of the sheet.
      sheet.removeRows(startIndex, count);
      sheet.removeColumns(startIndex, count);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Resize rows and columns

Use the `Sheet.setColumnWidthInPixel` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#setColumnWidthInPixel__anchor) and `Sheet.setRowHeightInPixel` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#setRowHeightInPixel__anchor) to resize columns and rows, respectively. The following code sample sets the first column height and row width to 200px.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
  
      const rowIndex = 0;
      const columnIndex = 0;
      const sizeInPixels = 200;
  
      sheet.setRowHeightInPixel(rowIndex, sizeInPixels);
      sheet.setColumnWidthInPixel(columnIndex, sizeInPixels);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Cells

Cells are the basic building blocks of a spreadsheet, used to enter data, text, or formulas. Each is identified by its row and column (e.g., B2) and can be styled, merged, or formatted. Users can edit cells directly through the formula bar or programmatically via an API.

You could, for example, develop a budgeting application that programmatically reads XLSX files and [applies a light-red background color to cells ](#apply-styles-to-a-cell)that don't match their expected format (e.g., invalid format, missing values). You'd use the `Cell.setStyle` API to change the background color of a specific cell.

### Access a single cell

The following code sample shows how to access a cell programmatically using the `Sheet.getCellAt` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#getCellAt__anchor) and alternatively the `Row.getCellAt` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Row.html#getCellAt__anchor).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
      let cell = sheet.getRowAt(0).getCellAt(0);
      
      // Alternatively, you can call the Sheet.getCellAt API directly.
      cell = sheet.getCellAt(0, 0);
      console.log(cell);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Access currently selected cells

The following code sample demonstrates how to programmatically access the currently selected cells using the following `SpreadsheetEditorManager` [APIs](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html):

* `getSelectedCells` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#getSelectedCells__anchor) to retrieve a `Cell[]`
* `getSelectedCellRange` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#getSelectedCellRange__anchor) to retrieve a `CellRange`

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const cells = spreadsheetEditorManager.getSelectedCells();
      const cellRange = spreadsheetEditorManager.getSelectedCellRange();
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Set a cell value

The following code sample shows how to set the value of a cell using different types of values, including strings, booleans, numbers, and dates. See the [Cell class documentation](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Cell.html) for a detailed look at the available APIs.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const cell = workbook
        .getSheetAt(0)
        .getRowAt(0)
        .getCellAt(0);
      
      // cell.setBooleanValue(false);
      // cell.setFormula('=SUM(5, 5)');
      // cell.setStringValue('Hello World');
      // cell.setDateValue('2025-01-01 09:00:00');
      cell.setNumericValue(100);
      console.log(cell);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Apply styles to a cell

The following code sample shows how to apply various styles to an individual cell using the `Cell.setStyle` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Cell.html#setStyle__anchor) and `Workbook.createFont` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Workbook.html#createFont).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const cell = workbook
        .getSheetAt(0)
        .getRowAt(0)
        .getCellAt(0);
        
      const font = workbook.createFont({
        fontFace: 'Times New Roman',
        pointSize: 12,
        color: 'red',
        bold: true,
        italic: true,
        underline: true
      });
      
      const cellStyle = cell.getStyle();
      cellStyle.font = font;
      cellStyle.horizontalAlignment = SpreadsheetEditor.Types.HorizontalAlignment.CENTER;
      cellStyle.verticalAlignment = SpreadsheetEditor.Types.VerticalAlignment.CENTER;
      cellStyle.backgroundColor = 'lightgreen';
      cellStyle.wrapText = SpreadsheetEditor.Types.TextWrap.OVERFLOW;
      
      cell.setStyle(cellStyle);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Apply styles to selected cells

The following code sample shows how to apply various styles to the actively selected cells using the `SpreadsheetEditorManager.setSelectedCellsStyle` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#setSelectedCellsStyle).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);

      const styleObject = {
        verticalAlignment: SpreadsheetEditor.Types.VerticalAlignment.CENTER,
        horizontalAlignment: SpreadsheetEditor.Types.HorizontalAlignment.CENTER,
        font: {
          fontFace: 'Times New Roman',
          pointSize: 12,
          color: '#000000',
          bold: true,
          italic: true,
          underline: true,
          strikeout: false
        }
      };
      
      spreadsheetEditorManager.setSelectedCellsStyle(styleObject);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Cell ranges

A cell range is a collection of one or more cells in a rectangular grouping. They are defined by their first and last row and column. Use cell ranges when you want to interact with groups of cells. See [CellRange class](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.CellRange.html) documentation.

### Create a cell range

Cell ranges are created via a constructor. They are defined either by a string representation (e.g., A1:B5) or by an object specifying the first and last row and column indices.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      // Two different ways of creating a cell range for A1:B5.
      const cellRange = new SpreadsheetEditor.CellRange('A1:B5');
      const cellRange2 = new SpreadsheetEditor.CellRange({
        firstRow: 0,
        firstColumn: 0,
        lastRow: 4,
        lastColumn: 1
      });
      
      // These will both log out 'A1:B5'.
      console.log(cellRange.rangeDisplayValue);
      console.log(cellRange2.rangeDisplayValue);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Select a cell range

Use the `SpreadsheetEditorManager.selectCellRange` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#selectCellRange__anchor) to programmatically select one or more cells. Calling this API will automatically scroll the viewer to the selected cell range. The following code sample shows how to select the cell range A1:B5.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const cellRange = new SpreadsheetEditor.CellRange('A1:B5');
      spreadsheetEditorManager.selectCellRange(cellRange);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Get currently selected cell range

Use the `SpreadsheetEditorManager.getSelectedCellRange` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorManager.html#getSelectedCellRange) to get a CellRange representation of the currently selected cells.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      const cellRange = spreadsheetEditorManager.getSelectedCellRange();
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Style a cell range

Use the `Sheet.setCellRangeStyle` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#setCellRangeStyle__anchor) and the `Sheet.setCellRangeBorder` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#setCellRangeBorder__anchor) to programmatically apply styling and borders to a cell range, respectively. Please note that calling these APIs will overwrite the existing styling. The following code sample shows how to apply a red background with dotted borders.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
  
      const style = workbook.createCellStyle({ backgroundColor: 'red' });
      const border = {
        color: 'black',
        style: SpreadsheetEditor.Types.BorderStyle.DOTTED,
        type: SpreadsheetEditor.Types.RangeBorderType.OUTSIDE,
      };
  
      const cellRange = new SpreadsheetEditor.CellRange('A1:F1');
      sheet.setCellRangeStyle(cellRange, style);
      sheet.setCellRangeBorder(cellRange, border);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Formula bar

The formula bar is where users can view and edit the contents of active cells. It serves as a single-line input field that supports both plain values and formulas (e.g., `=A1+B1`). When a cell is selected, its content automatically appears in the formula bar for quick inspection or modification. We have a [full list of supported formulas](/web/spreadsheet-editor/formulas.md) you can review to see which best support your needs.

### Set a cell formula

The following code sample shows how to programmatically set a formula on a specific cell using the `Cell.setFormula` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Cell.html#setFormula).

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const cell = workbook
        .getSheetAt(0)
        .getRowAt(0)
        .getCellAt(0);
      
      cell.setFormula('=SUM(5, 95)');
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Images

Images are stored individually in each sheet. You can read, add, and remove images from any sheet. The following image formats are supported:

* BMP
* GIF
* JPEG
* PNG

### Get images

Use the `Sheet.getImage` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#getImage__anchor) to get images from a specific sheet. With this, you can access an image's size, position, and original source. Refer to the [SpreadsheetEditorImage class](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.SpreadsheetEditorImage.html) to see all available properties.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
    
      if (sheet.imagesCount > 0) {
        const image = sheet.getImage(0);
        console.log(image);
      }  
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Add images

Use the `Sheet.addImage` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#addImage__anchor) to add images to a specific sheet. Images can be added by passing a relative path, HTTP(S) URL, or Base64-encoded data URL. If position and size are not provided, the image is placed in the top-left corner with a default size of 250x250 pixels.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, async () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);

      await sheet.addImage('./path/to/relative/image.png');
      await sheet.addImage('https://www.example.com/image.png', {
        x: 100,
        y: 100,
        width: 500,
        height: 300
      });
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Remove images

Use the `Sheet.removeImage` [API](https://sdk.apryse.com/api/web/Core.SpreadsheetEditor.Sheet.html#removeImage__anchor) to remove images from a specific sheet. The following code sample shows how to remove the first image from the first sheet.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const workbook = spreadsheetEditorManager.getWorkbook();
      const sheet = workbook.getSheetAt(0);
      
      if (sheet.imagesCount > 0) {
        sheet.removeImage(0); 
      }
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Undo and redo

The Spreadsheet Editor supports undo and redo for a variety of actions, such as:

* Editing cell values.
* Changing cell styles.
* Adding or removing sheets.
* Resizing columns and rows.
* Moving and resizing charts.

The following code sample shows how to detect if there are actions that can be undone or redone.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    const { documentViewer, SpreadsheetEditor } = instance.Core;
    const spreadsheetEditorManager = documentViewer.getSpreadsheetEditorManager();
    const SpreadsheetEditorEvents = SpreadsheetEditor.SpreadsheetEditorManager.Events;
    
    spreadsheetEditorManager.addEventListener(SpreadsheetEditorEvents.SPREADSHEET_EDITOR_READY, async () => {
      spreadsheetEditorManager.setEditMode(SpreadsheetEditor.SpreadsheetEditorEditMode.EDITING);
      const spreadsheetEditorHistoryManager = spreadsheetEditorManager.getSpreadsheetEditorHistoryManager();
    
      if (spreadsheetEditorHistoryManager.canUndo()) {
        await spreadsheetEditorHistoryManager.undo(); 
      }
      
      if (spreadsheetEditorHistoryManager.canRedo()) {
        await spreasdheetEditorHistoryManager.redo();
      }
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/spreadsheet-editor/edit-mode.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
