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

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>
);

Export Options

Image Format

You can export in two formats:

  • PNG (default): "image/png" - Lossless, supports transparency

  • JPEG: "image/jpeg" - Compressed, smaller file size

// 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:

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:

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:

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:

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

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:

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:

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

Documentation

Create screenshots for documentation or tutorials:

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.

Last updated

Was this helpful?