> For the complete documentation index, see [llms.txt](https://docs.rowsncolumns.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rowsncolumns.app/configuration/features/export-canvas-as-image.md).

# Export canvas as image

Export the entire visible canvas or part of the canvas as an image

The spreadsheet provides functionality to export regions of the canvas as images, useful for generating reports, sharing data visualizations, or creating documentation.

## Exporting a Sheet Region

You can export specific regions of your spreadsheet as PNG or JPEG images using the `exportRegion` function from the `useSpreadsheet` hook.

### Basic Usage

{% code overflow="wrap" %}

```tsx
import { SpreadsheetProvider, CanvasGrid, useSpreadsheet } from "@rowsncolumns/spreadsheet";

const MySpreadsheet = () => {
  const { exportRegion } = useSpreadsheet()

  const handleExport = () => {
    exportRegion?.(
      {
        startRowIndex: 1,
        endRowIndex: 10,
        startColumnIndex: 1,
        endColumnIndex: 5,
      },
      "my-spreadsheet-export",  // filename (without extension)
      "image/png"                // MIME type
    );
  };
  
  return (
    <>
      <button onClick={handleExport}>
        Export Region as Image
      </button>
      <CanvasGrid />
    </>
  );
};

const App = () => (
  <SpreadsheetProvider>
    <MySpreadsheet />
  </SpreadsheetProvider>
);
```

{% endcode %}

### Export Options

#### Image Format

You can export in two formats:

* **PNG** (default): `"image/png"` - Lossless, supports transparency
* **JPEG**: `"image/jpeg"` - Compressed, smaller file size

```tsx
// Export as PNG
exportRegion?.(range, "export", "image/png");

// Export as JPEG
exportRegion?.(range, "export", "image/jpeg");
```

#### Range Selection

The range object specifies which cells to include in the export:

```tsx
const range = {
  startRowIndex: 1,   // Starting row (1-indexed, 0 is header)
  endRowIndex: 20,    // Ending row (inclusive)
  startColumnIndex: 1,  // Starting column (1-indexed, 0 is header)
  endColumnIndex: 10,   // Ending column (inclusive)
};

exportRegion?.(range, "quarterly-report", "image/png");
```

### Export Current Selection

You can export the currently selected range:

```tsx
import { useSpreadsheet } from "@rowsncolumns/spreadsheet";
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";

const MySpreadsheet = () => {
  const { exportRegion } = useSpreadsheet();
  const { selections, activeCell } = useSpreadsheetState({
    // ... configuration
  });

  const exportSelection = () => {
    const selection = selections.length > 0
      ? selections[selections.length - 1].range
      : {
          startRowIndex: activeCell.rowIndex,
          endRowIndex: activeCell.rowIndex,
          startColumnIndex: activeCell.columnIndex,
          endColumnIndex: activeCell.columnIndex,
        };

    exportRegion?.(selection, "selected-area", "image/png");
  };

  return <button onClick={exportSelection}>Export Selection</button>;
};
```

### Export with Custom Filename

Generate dynamic filenames based on date, sheet name, or other criteria:

```tsx
const exportWithTimestamp = () => {
  const timestamp = new Date().toISOString().split('T')[0];
  const filename = `spreadsheet-export-${timestamp}`;
  
  exportRegion?.(range, filename, "image/png");
};

const exportBySheetName = (sheetName: string) => {
  const filename = `${sheetName.toLowerCase().replace(/\s+/g, '-')}-export`;
  
  exportRegion?.(range, filename, "image/png");
};
```

## Exporting Entire Canvas

While there's no direct "export entire canvas" function, you can export the entire visible sheet by specifying the full range:

```tsx
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";

const { rowCount, columnCount, activeSheetId } = useSpreadsheetState({
  // ... configuration
});

const exportEntireSheet = () => {
  exportRegion?.(
    {
      startRowIndex: 1,
      endRowIndex: rowCount - 1,
      startColumnIndex: 1,
      endColumnIndex: columnCount - 1,
    },
    `sheet-${activeSheetId}-full`,
    "image/png"
  );
};
```

## Complete Example

```tsx
import React, { useState } from "react";
import {
  SpreadsheetProvider,
  CanvasGrid,
  useSpreadsheet,
} from "@rowsncolumns/spreadsheet";
import {
  useSpreadsheetState,
  type SheetData,
} from "@rowsncolumns/spreadsheet-state";

function SpreadsheetWithExport() {
  const [sheets, setSheets] = useState([
    { sheetId: 1, rowCount: 100, columnCount: 26, title: "Sales Data" }
  ]);
  const [sheetData, setSheetData] = useState<SheetData>({});

  const {
    activeCell,
    activeSheetId,
    selections,
    rowCount,
    columnCount,
    getCellData,
    getSheetName,
  } = useSpreadsheetState({
    sheets,
    sheetData,
    onChangeSheets: setSheets,
    onChangeSheetData: setSheetData,
  });

  return (
    <SpreadsheetProvider>
      <ExportToolbar
        sheetName={getSheetName(activeSheetId)}
        selections={selections}
        activeCell={activeCell}
        rowCount={rowCount}
        columnCount={columnCount}
      />
      <CanvasGrid
        sheetId={activeSheetId}
        activeCell={activeCell}
        selections={selections}
        getCellData={getCellData}
      />
    </SpreadsheetProvider>
  );
}

function ExportToolbar({ sheetName, selections, activeCell, rowCount, columnCount }) {
  const { exportRegion } = useSpreadsheet();

  const exportSelection = () => {
    const range = selections.length > 0
      ? selections[selections.length - 1].range
      : {
          startRowIndex: activeCell.rowIndex,
          endRowIndex: activeCell.rowIndex,
          startColumnIndex: activeCell.columnIndex,
          endColumnIndex: activeCell.columnIndex,
        };

    exportRegion?.(range, `${sheetName}-selection`, "image/png");
  };

  const exportFullSheet = () => {
    exportRegion?.(
      {
        startRowIndex: 1,
        endRowIndex: rowCount - 1,
        startColumnIndex: 1,
        endColumnIndex: columnCount - 1,
      },
      `${sheetName}-full`,
      "image/png"
    );
  };

  return (
    <div className="flex gap-2 p-2">
      <button onClick={exportSelection}>
        Export Selection
      </button>
      <button onClick={exportFullSheet}>
        Export Full Sheet
      </button>
    </div>
  );
}
```

## Use Cases

### Report Generation

Export specific data ranges for inclusion in reports:

```tsx
const exportQuarterlyReport = () => {
  exportRegion?.(
    {
      startRowIndex: 1,
      endRowIndex: 15,
      startColumnIndex: 1,
      endColumnIndex: 8,
    },
    "Q1-2024-report",
    "image/png"
  );
};
```

### Data Visualization Sharing

Export charts and formatted data for sharing:

```tsx
const exportChart = (chartRange) => {
  exportRegion?.(chartRange, "sales-chart", "image/png");
};
```

### Documentation

Create screenshots for documentation or tutorials:

```tsx
const exportExample = () => {
  exportRegion?.(
    exampleRange,
    "documentation-example",
    "image/png"
  );
};
```

## Limitations

* Only the visible/rendered portion of the canvas can be exported
* Hidden rows and columns are not included in the export
* The export captures the current visual state (colors, formatting, etc.)
* Very large ranges may take longer to export
* Export quality depends on the canvas resolution

## Best Practices

1. **Use descriptive filenames**: Include dates, sheet names, or identifiers
2. **Choose appropriate format**: Use PNG for detailed data, JPEG for photographs
3. **Limit range size**: Export only necessary cells for better performance
4. **Provide user feedback**: Show loading states during export
5. **Validate ranges**: Ensure row/column indices are within bounds

## Browser Compatibility

The export functionality works in all modern browsers that support:

* Canvas API
* Blob API
* Download attribute on anchor elements

For older browsers, consider providing a fallback or polyfill.
