Paint Format
Copy formatting from one cell or range and apply it to another
The Paint Format feature, also known as Format Painter, allows users to copy formatting from one cell or range and apply it to another location. This is useful for quickly applying consistent formatting across your spreadsheet.
Overview
Paint Format copies all visual formatting from the source cells (colors, borders, fonts, alignment, number formats, etc.) and applies it to target cells, without affecting the cell values.
Basic Usage
Using the Toolbar Button
The easiest way to use Paint Format is through the ButtonPaintFormat toolbar button:
import {
SpreadsheetProvider,
CanvasGrid,
Toolbar,
ButtonPaintFormat,
} from "@rowsncolumns/spreadsheet";
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";
function MySpreadsheet() {
const {
activeCell,
activeSheetId,
selections,
onSavePaintFormat,
isPaintFormatActive,
// ... other hook values
} = useSpreadsheetState({
sheets,
sheetData,
onChangeSheets,
onChangeSheetData,
});
return (
<SpreadsheetProvider>
<Toolbar>
<ButtonPaintFormat
isActive={isPaintFormatActive}
onClick={() =>
onSavePaintFormat(activeSheetId, activeCell, selections)
}
/>
</Toolbar>
<CanvasGrid
sheetId={activeSheetId}
activeCell={activeCell}
selections={selections}
// ... other props
/>
</SpreadsheetProvider>
);
}How It Works
1. Copy Format (Activate Paint Format)
Click the Paint Format button or call onSavePaintFormat to copy formatting from the currently selected cells:
// Save formatting from current selection
onSavePaintFormat(activeSheetId, activeCell, selections);When paint format is active, isPaintFormatActive returns true, which can be used to show visual feedback.
2. Apply Format
Once activated, simply select the target cells where you want to apply the formatting. The spreadsheet automatically applies the copied formatting to the new selection.
3. Deactivate
Paint format automatically deactivates after applying to one selection. To cancel without applying, click the Paint Format button again.
Programmatic Usage
You can also use paint format programmatically:
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";
const {
onSavePaintFormat,
onApplyPaintFormat,
isPaintFormatActive,
paintFormat, // Direct function to paint from one range to another
} = useSpreadsheetState({
// ... configuration
});
// Copy formatting from range A1:B2
onSavePaintFormat(
1, // sheetId
{ rowIndex: 1, columnIndex: 1 }, // activeCell
[{
range: {
startRowIndex: 1,
endRowIndex: 2,
startColumnIndex: 1,
endColumnIndex: 2,
}
}]
);
// Or paint directly from one range to another
paintFormat(
{
startRowIndex: 1,
endRowIndex: 2,
startColumnIndex: 1,
endColumnIndex: 2,
sheetId: 1,
},
{
startRowIndex: 5,
endRowIndex: 6,
startColumnIndex: 3,
endColumnIndex: 4,
sheetId: 1,
}
);What Gets Copied
Paint Format copies the following formatting properties:
Text formatting: Font family, font size, bold, italic, underline, strikethrough
Colors: Text color, background color
Borders: All border styles and colors
Alignment: Horizontal and vertical alignment
Number formats: Currency, percentage, date, custom formats
Text wrapping: Wrap, overflow, or clip
Indentation: Text indentation levels
What Does NOT Get Copied
Paint Format does NOT copy:
Cell values or formulas
Cell comments/notes
Data validation rules
Conditional formatting rules
Protected range settings
Merged cell configuration
Complete Example
import React, { useState } from "react";
import {
SpreadsheetProvider,
CanvasGrid,
Toolbar,
ButtonPaintFormat,
ToolbarSeparator,
ButtonBold,
ButtonItalic,
BackgroundColorSelector,
} from "@rowsncolumns/spreadsheet";
import {
useSpreadsheetState,
type SheetData,
} from "@rowsncolumns/spreadsheet-state";
function SpreadsheetWithPaintFormat() {
const [sheets, setSheets] = useState([
{ sheetId: 1, rowCount: 100, columnCount: 26, title: "Sheet 1" }
]);
const [sheetData, setSheetData] = useState<SheetData>({});
const {
activeCell,
activeSheetId,
selections,
getCellData,
getEffectiveFormat,
onChangeActiveCell,
onChangeSelections,
onChangeFormatting,
onSavePaintFormat,
isPaintFormatActive,
} = useSpreadsheetState({
sheets,
sheetData,
onChangeSheets: setSheets,
onChangeSheetData: setSheetData,
});
const currentCellFormat = getEffectiveFormat(
activeSheetId,
activeCell.rowIndex,
activeCell.columnIndex
);
return (
<SpreadsheetProvider>
<Toolbar>
<ButtonBold
isActive={currentCellFormat?.textFormat?.bold}
onClick={() =>
onChangeFormatting(
activeSheetId,
activeCell,
selections,
"textFormat",
{ bold: !currentCellFormat?.textFormat?.bold }
)
}
/>
<ButtonItalic
isActive={currentCellFormat?.textFormat?.italic}
onClick={() =>
onChangeFormatting(
activeSheetId,
activeCell,
selections,
"textFormat",
{ italic: !currentCellFormat?.textFormat?.italic }
)
}
/>
<BackgroundColorSelector
color={currentCellFormat?.backgroundColor}
onChange={(color) =>
onChangeFormatting(
activeSheetId,
activeCell,
selections,
"backgroundColor",
color
)
}
/>
<ToolbarSeparator />
<ButtonPaintFormat
isActive={isPaintFormatActive}
onClick={() =>
onSavePaintFormat(activeSheetId, activeCell, selections)
}
/>
</Toolbar>
<CanvasGrid
sheetId={activeSheetId}
activeCell={activeCell}
selections={selections}
getCellData={getCellData}
onChangeActiveCell={onChangeActiveCell}
onChangeSelections={onChangeSelections}
/>
</SpreadsheetProvider>
);
}Keyboard Shortcut
Paint Format can also be activated via keyboard shortcuts (implementation dependent on your configuration):
// Example: Activate paint format with Ctrl+Shift+C (copy format)
// Then apply with Ctrl+Shift+V (paste format)Use Cases
Consistent Table Headers
Apply the same header formatting to multiple tables:
Format one header cell (bold, background color, borders)
Click Paint Format
Select other header cells to apply the same style
Standardizing Reports
Quickly apply consistent formatting across similar data sections:
Format one complete section
Use Paint Format to copy it
Apply to other sections
Color Coding
Apply color coding patterns to categorize data:
Set up one cell with specific colors
Paint format to similar categories
Best Practices
Format once, apply many: Create template cells with desired formatting, then use Paint Format to replicate
Visual feedback: The
isPaintFormatActivestate should be used to provide visual indication that paint format mode is activeUndo support: Paint format operations are tracked in undo history
Performance: Paint format is efficient even for large ranges
API Reference
useSpreadsheetState Returns
onSavePaintFormat
(sheetId, activeCell, selections) => void
Saves formatting from selection for painting
onApplyPaintFormat
(sheetId, activeCell, selections) => void
Applies saved formatting to new selection
isPaintFormatActive
boolean
Whether paint format mode is active
paintFormat
(sourceRange, targetRange) => void
Directly paint from one range to another
Limitations
Paint format is a client-side operation and works with the current spreadsheet state
Very large ranges may take a moment to process
Formatting from merged cells requires special handling
Troubleshooting
Paint Format Not Working
Ensure you have the necessary callbacks:
const {
onSavePaintFormat,
isPaintFormatActive,
// These are required for paint format to work
onChangeFormatting,
getEffectiveFormat,
} = useSpreadsheetState({
// configuration
});Visual Feedback Not Showing
Use isPaintFormatActive to style the button:
<ButtonPaintFormat
isActive={isPaintFormatActive} // This provides visual feedback
onClick={handlePaintFormat}
/>Last updated
Was this helpful?