> 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

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.
