Excel Import/Export
Excel Import/Export
Section titled “Excel Import/Export”The ExcelPlugin provides Excel file import and export via SheetJS (Apache-2.0). SheetJS is lazy-loaded from CDN on first use — no bundle size impact until you actually import or export.
View source code
import { useRef, useEffect, useState } from 'react';import { WitTable } from '@witqq/spreadsheet-react';import type { WitTableRef } from '@witqq/spreadsheet-react';import { ExcelPlugin } from '@witqq/spreadsheet-plugins';import { DemoWrapper } from './DemoWrapper';import { generateEmployees, employeeColumns } from './generate-data';import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(15);
export function ExcelDemo() { const { witTheme } = useSiteTheme(); const tableRef = useRef<WitTableRef>(null); const pluginRef = useRef<ExcelPlugin | null>(null); const fileInputRef = useRef<HTMLInputElement>(null); const [status, setStatus] = useState('Ready');
useEffect(() => { const engine = tableRef.current?.getInstance(); if (!engine) return; const plugin = new ExcelPlugin(); engine.installPlugin(plugin); pluginRef.current = plugin; }, []);
const handleExport = async () => { if (!pluginRef.current) return; try { setStatus('Exporting...'); const buffer = await pluginRef.current.exportExcel({ sheetName: 'Employees' }); const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'witqq-export.xlsx'; a.click(); URL.revokeObjectURL(url); setStatus('Exported to witqq-export.xlsx'); } catch (e) { setStatus(`Export error: ${e instanceof Error ? e.message : String(e)}`); } };
const handleImport = async (e: React.ChangeEvent<HTMLInputElement>) => { const file = e.target.files?.[0]; if (!file || !pluginRef.current) return; try { setStatus(`Importing ${file.name}...`); const buffer = await file.arrayBuffer(); const result = await pluginRef.current.importExcel(buffer); setStatus(`Imported ${result.rowCount} rows from "${result.sheetName}"`); } catch (err) { setStatus(`Import error: ${err instanceof Error ? err.message : String(err)}`); } e.target.value = ''; };
return ( <DemoWrapper title="Live Demo" description="Upload an .xlsx file or export the current table to Excel." height={440}> <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}> <div style={{ padding: '0.5rem 0.75rem', borderBottom: '1px solid #e2e8f0', flexShrink: 0, display: 'flex', gap: '0.5rem', alignItems: 'center' }}> <input ref={fileInputRef} type="file" accept=".xlsx" onChange={handleImport} style={{ display: 'none' }} /> <button onClick={() => fileInputRef.current?.click()} style={{ padding: '4px 12px', cursor: 'pointer' }}>📥 Import Excel</button> <button onClick={handleExport} style={{ padding: '4px 12px', cursor: 'pointer' }}>📤 Export Excel</button> <span style={{ fontSize: '0.8rem', color: '#64748b' }}>{status}</span> </div> <div style={{ flex: 1 }}> <WitTable theme={witTheme} ref={tableRef} columns={employeeColumns} data={data} showRowNumbers editable style={{ width: '100%', height: '100%' }} /> </div> </div> </DemoWrapper> );}Installation
Section titled “Installation”import { ExcelPlugin } from '@witqq/spreadsheet-plugins';
const excelPlugin = new ExcelPlugin();engine.installPlugin(excelPlugin);Import
Section titled “Import”importExcel
Section titled “importExcel”importExcel(buffer: ArrayBuffer, sheetIndex?: number): Promise<ExcelImportResult>Reads an .xlsx file buffer and returns structured data ready to apply to the table.
interface ExcelImportResult { columns: ColumnDef[]; // Auto-detected column definitions rowCount: number; // Number of data rows sheetName: string; // Name of the imported sheet}Features:
- Auto-detects column types from cell data (string, number, date, boolean)
- Preserves column widths from the Excel file
- Handles merged regions
File Input Example
Section titled “File Input Example”import { ExcelPlugin } from '@witqq/spreadsheet-plugins';import { WitTable, WitTableRef } from '@witqq/spreadsheet-react';
function App() { const ref = useRef<WitTableRef>(null); const excelRef = useRef<ExcelPlugin>(); const [columns, setColumns] = useState<ColumnDef[]>([]); const [data, setData] = useState<Record<string, unknown>[]>([]);
useEffect(() => { const plugin = new ExcelPlugin(); excelRef.current = plugin; ref.current?.installPlugin(plugin); }, []);
const handleImport = async (e: React.ChangeEvent<HTMLInputElement>) => { const file = e.target.files?.[0]; if (!file || !excelRef.current) return;
const buffer = await file.arrayBuffer(); const result = await excelRef.current.importExcel(buffer);
setColumns(result.columns); // Data is applied to the engine internally; // update React state to match };
return ( <div> <input type="file" accept=".xlsx,.xls" onChange={handleImport} /> <WitTable ref={ref} columns={columns} data={data} /> </div> );}Export
Section titled “Export”exportExcel
Section titled “exportExcel”exportExcel(options?: ExcelExportOptions): Promise<ArrayBuffer>Exports the current table data as an .xlsx file buffer.
interface ExcelExportOptions { sheetName?: string; // Sheet name (default: 'Sheet1') includeHeaders?: boolean; // Include column headers (default: true) maxRows?: number; // Limit exported rows}Export Button Example
Section titled “Export Button Example”const handleExport = async () => { if (!excelRef.current) return;
const buffer = await excelRef.current.exportExcel({ sheetName: 'Sales Data', includeHeaders: true, });
// Trigger browser download const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'export.xlsx'; a.click(); URL.revokeObjectURL(url);};
return <button onClick={handleExport}>Export to Excel</button>;SheetJS Loading
Section titled “SheetJS Loading”SheetJS (v0.20.3) is loaded from CDN on first importExcel or exportExcel call. This keeps the core bundle small — the ~300KB SheetJS library is only fetched when needed.
If you need to pre-load SheetJS (e.g. to avoid latency on first use), the plugin handles caching automatically after the first load.