react-spreadsheet-editor
v1.0.7
Published
A powerful React spreadsheet component with Excel import/export
Readme
React Spreadsheet Editor
A powerful, developer-friendly React spreadsheet component with Excel import/export, formulas, and styling capabilities.
Features
- 📊 Excel Import/Export - Import .xlsx files and export to Excel or JSON
- 🧮 Formula Support - SUM, AVERAGE, MIN, MAX, COUNT, IF, CONCAT and more
- 🎨 Cell Styling - Bold, italic, underline, text alignment, colors
- 📏 Resizable Columns - Drag to resize columns with minimum width constraints
- ⌨️ Keyboard Navigation - Arrow keys, Enter, Tab navigation
- 🔄 Undo/Redo - Full history management with Ctrl+Z/Ctrl+Y
- 🎯 TypeScript - Full TypeScript support with type definitions
- 🌙 Dark Mode - Built-in dark mode support
- 📱 Responsive - Works on desktop and mobile devices
Table of Contents
- Installation
- Quick Start
- Props
- Advanced Usage
- Data Structure
- Utility Functions
- Formulas
- Keyboard Shortcuts
- Development
- Contributing
- License
Installation
npm install react-spreadsheet-editor
# or
yarn add react-spreadsheet-editor
# or
bun add react-spreadsheet-editorNote: This package has no external dependencies beyond React. All styles are self-contained.
Quick Start
import React from 'react';
import { SpreadsheetEditor } from 'react-spreadsheet-editor';
import 'react-spreadsheet-editor/styles.css'; // Import styles
function App() {
const handleChange = (data: any) => {
console.log('Spreadsheet data changed:', data);
};
const handleExport = (data: any) => {
console.log('Exported data:', data);
};
const handleImport = (data: any) => {
console.log('Imported data:', data);
};
return (
<div style={{ height: '600px' }}>
<SpreadsheetEditor
onChange={handleChange}
onExport={handleExport}
onImport={handleImport}
/>
</div>
);
}
export default App;Props
| Prop | Type | Description |
|------|------|-------------|
| initialData | SpreadsheetData | Initial spreadsheet data |
| onChange | (data: SpreadsheetData) => void | Called when data changes |
| onExport | (data: SpreadsheetData) => void | Called when data is exported |
| onImport | (data: SpreadsheetData) => void | Called when data is imported |
| className | string | Additional CSS classes |
| rowCount | number | Number of rows (default: 100) |
| columnCount | number | Number of columns (default: 26) |
Advanced Usage
With Initial Data
import { SpreadsheetEditor, createEmptySpreadsheet } from 'react-spreadsheet-editor';
const initialData = createEmptySpreadsheet();
// Add some initial data
initialData.cells['A1'] = { value: 'Hello' };
initialData.cells['B1'] = { value: 'World' };
<SpreadsheetEditor initialData={initialData} />Custom Grid Size
<SpreadsheetEditor
rowCount={50}
columnCount={15}
onChange={handleChange}
/>Custom Styling
<SpreadsheetEditor
className="border rounded-lg shadow-lg"
onChange={handleChange}
/>Working with Formulas
The spreadsheet supports various formulas:
=SUM(A1:A10) // Sum of range
=AVERAGE(B1:B5) // Average of range
=MIN(C1:C10) // Minimum value
=MAX(D1:D10) // Maximum value
=COUNT(E1:E10) // Count non-empty cells
=IF(F1>10,"High","Low") // Conditional logic
=CONCAT(G1," ",H1) // Concatenate stringsData Structure
interface SpreadsheetData {
cells: Record<string, Cell>;
columnWidths: Record<number, number>;
rowHeights: Record<number, number>;
rowCount: number;
columnCount: number;
}
interface Cell {
value: string;
formula?: string;
computedValue?: string | number;
style?: CellStyle;
}
interface CellStyle {
bold?: boolean;
italic?: boolean;
underline?: boolean;
strikethrough?: boolean;
textAlign?: 'left' | 'center' | 'right';
backgroundColor?: string;
textColor?: string;
}Utility Functions
import {
getCellId,
getColumnLabel,
parseCellId,
createEmptySpreadsheet,
exportToJSON,
computeAllCells
} from 'react-spreadsheet-editor';
// Get cell ID from coordinates
const cellId = getCellId(0, 0); // "A1"
// Get column label from index
const label = getColumnLabel(0); // "A"
// Parse cell ID to coordinates
const position = parseCellId("B2"); // { row: 1, col: 1 }
// Create empty spreadsheet
const data = createEmptySpreadsheet();
// Export to JSON format
const json = exportToJSON(spreadsheetData);
// Compute all formulas
const computed = computeAllCells(spreadsheetData);Formulas
The spreadsheet supports a variety of built-in formulas:
Math Functions
SUM(range)- Sum all values in a rangeAVERAGE(range)- Calculate average of valuesMIN(range)- Find minimum valueMAX(range)- Find maximum valueCOUNT(range)- Count non-empty cells
Text Functions
CONCAT(str1, str2, ...)- Combine stringsIF(condition, true_value, false_value)- Conditional formula
Keyboard Shortcuts
| Shortcut | Action | |----------|--------| | Arrow Keys | Navigate between cells | | Enter | Edit selected cell | | Escape | Cancel editing | | Ctrl+Z | Undo | | Ctrl+Y / Ctrl+Shift+Z | Redo | | Ctrl+B | Toggle bold | | Ctrl+I | Toggle italic | | Ctrl+U | Toggle underline |
Styling Requirements
The component uses scoped CSS styles that are included in the package. Simply import the CSS file:
import 'react-spreadsheet-editor/styles.css';The styles are self-contained and don't require Tailwind CSS or any external dependencies. They include CSS variables for both light and dark themes.
Development
Prerequisites
- Node.js 16+ or Bun
- npm, yarn, or bun package manager
Setup
# Clone the repository
git clone https://github.com/MosesAweda/React-Spreadsheet-Editor.git
cd React-Spreadsheet-Editor
# Install dependencies
npm install
# or
bun install
# Start development server
npm run dev
# or
bun run devThe development server will start at http://localhost:5173
Build
# Build for production
npm run build
# Build for development
npm run build:dev
# Preview build output
npm run previewTesting
# Run tests once
npm run test
# Run tests in watch mode
npm run test:watchLinting
npm run lintProject Structure
src/
├── components/
│ ├── Spreadsheet/ # Main spreadsheet component
│ │ ├── SpreadsheetEditor.tsx # Main editor component
│ │ ├── SpreadsheetGrid.tsx # Grid display
│ │ ├── SpreadsheetCell.tsx # Individual cell
│ │ ├── FormulaBar.tsx # Formula input bar
│ │ ├── SpreadsheetToolbar.tsx # Toolbar with actions
│ │ └── index.ts
│ ├── ui/ # UI components (Radix UI + Shadcn)
│ └── NavLink.tsx
├── hooks/ # Custom React hooks
├── lib/
│ ├── spreadsheet/
│ │ ├── types.ts # Type definitions
│ │ ├── formulas.ts # Formula computation
│ │ └── excelUtils.ts # Excel import/export
│ └── utils.ts
├── pages/ # App pages
├── test/ # Test files
└── App.tsxBrowser Support
- Chrome 60+
- Firefox 60+
- Safari 12+
- Edge 79+
Contributing
We welcome contributions! Here's how to get started:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes and commit them (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code follows the existing code style and includes appropriate tests.
License
MIT © Moses Aweda
Support
- 📧 Email: [email protected]
- 🐛 Issues: GitHub Issues
- 📖 Documentation: GitHub Wiki
Acknowledgments
Built with:
- React
- Vite
- TypeScript
- Tailwind CSS
- Lucide React (for icons)
