# 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.


---

# Agent Instructions: 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:

```
GET https://docs.rowsncolumns.app/configuration/features/export-canvas-as-image.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
