一个功能强大的 Excel 风格可编辑表格组件,基于 React + TypeScript + Vite 构建,支持表达式计算、自动完成、排序、搜索等丰富功能。
price*count)1+2*2+3),可被其他列引用计算npm install
npm run dev
npm run build
npm run preview
import { useRef, useState } from 'react'
import EditableTable from '@/components/EditableTable'
import { ColumnConfig, ColumnType, TableRow, TableRef } from '@/types/table'
function App() {
const tableRef = useRef<TableRef>(null)
const [data, setData] = useState<TableRow[]>([
{ id: '1', name: 'iPhone 15', price: 5999, count: 2 }
])
const columns: ColumnConfig[] = [
{ key: 'name', title: '商品名称', type: ColumnType.TEXT, editable: true },
{ key: 'price', title: '单价', type: ColumnType.NUMBER, editable: true },
{ key: 'count', title: '数量', type: ColumnType.NUMBER, editable: true },
]
return (
<EditableTable
ref={tableRef}
columns={columns}
data={data}
onChange={setData}
enableAutoAddRow={true}
/>
)
}
const columns: ColumnConfig[] = [
{ key: 'price', title: '单价', type: ColumnType.NUMBER, editable: true },
{ key: 'count', title: '数量', type: ColumnType.NUMBER, editable: true },
{
key: 'total',
title: '总价',
type: ColumnType.REFERENCE,
expression: 'price*count', // 自动计算
editable: false
},
]
const searchCities = async (searchValue: string) => {
const results = await fetch(`/api/cities?q=${searchValue}`)
return results.json()
}
const columns: ColumnConfig[] = [
{
key: 'city',
title: '城市',
type: ColumnType.AUTOCOMPLETE,
editable: true,
autoComplete: {
request: searchCities,
debounceDelay: 300,
placeholder: '请输入城市名称...',
onSelect: (option, rowIndex) => {
// 级联填充其他列
tableRef.current?.batchUpdateCells(rowIndex, {
province: option.extra.province,
areaCode: option.extra.areaCode,
})
},
},
},
]
<EditableTable
columns={columns}
data={data}
search={{
enabled: true,
placeholder: '搜索商品...',
searchableColumns: ['name', 'price'], // 只搜索这些列
}}
/>
const columns: ColumnConfig[] = [
{
key: 'price',
title: '单价',
type: ColumnType.NUMBER,
sortable: true // 启用排序
},
]
<EditableTable
columns={columns}
data={data}
actionColumn={{
enabled: true,
showDelete: true,
showCopy: true,
onBeforeDelete: (row) => {
return window.confirm(`确定要删除 ${row.name} 吗?`)
},
onAfterCopy: (originalRow, newRow) => {
console.log('已复制行:', newRow)
},
}}
/>
<EditableTable
columns={columns}
data={data}
batchOperation={{
enabled: true,
showCopyToClipboard: true,
showImportFromClipboard: true,
onAfterCopy: (selectedRows) => {
alert(`已复制 ${selectedRows.length} 行数据`)
},
}}
/>
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
columns | ColumnConfig[] | 必填 | 列配置数组 |
data | TableRow[] | 必填 | 表格数据 |
enableAutoAddRow | boolean | true | 是否启用自动新增行 |
onSubmit | (data: TableRow[]) => void | - | 提交数据回调 |
onCellChange | (rowId, columnKey, value) => void | - | 单元格变更回调 |
onChange | (data: TableRow[]) => void | - | 数据变更回调(受控模式) |
onCreateRow | () => TableRow | - | 自定义创建新行方法 |
search | SearchConfig | - | 搜索配置 |
actionColumn | ActionColumnConfig | - | 操作列配置 |
batchOperation | BatchOperationConfig | - | 多选操作配置 |
| 属性 | 类型 | 说明 |
|---|---|---|
key | string | 列的唯一标识 |
title | string | 列标题 |
type | ColumnType | 列类型 |
width | number | 列宽度 |
editable | boolean | 是否可编辑 |
sortable | boolean | 是否可排序 |
expression | string | 引用列表达式(如 price*count) |
autoComplete | AutoCompleteConfig | 自动完成配置 |
select | SelectConfig | 下拉选择配置 |
tags | TagConfig[] | 标签配置 |
render | (value, row) => ReactNode | 自定义渲染 |
customSort | (a, b, direction) => number | 自定义排序函数 |
TEXT: 文本类型NUMBER: 数字类型TAG: 标签类型AUTOCOMPLETE: 自动完成类型SELECT: 下拉选择类型FORMULA_TEXT: 公式文本类型REFERENCE: 引用计算类型const tableRef = useRef<TableRef>(null)
// 添加行
tableRef.current?.addRow(customRow)
// 更新单元格
tableRef.current?.updateCell(rowIndex, columnKey, value)
// 批量更新多个单元格
tableRef.current?.batchUpdateCells(rowIndex, {
province: '北京',
areaCode: '010'
})
普通文本输入,支持任意字符。
只允许输入数字,自动过滤非数字字符。
预定义的标签选项,输入匹配值后显示对应标签样式。
1+2*2+3)price*count*discount)项目提供了完整的表达式计算工具(src/utils/expression.ts):
evaluateExpression(expression): 计算纯数字表达式evaluateExpressionWithColumnNames(expression, row): 计算包含列名的表达式isValidFormulaText(text): 验证是否是有效的公式文本提供了防抖函数(src/utils/debounce.ts),用于优化自动完成等场景。
react-table-plus/ ├── src/ │ ├── components/ │ │ ├── EditableTable/ │ │ │ ├── index.tsx # 主表格组件 │ │ │ ├── EditableCell.tsx # 可编辑单元格 │ │ │ ├── AutoCompleteInput.tsx # 自动完成输入 │ │ │ └── SelectInput.tsx # 下拉选择输入 │ │ └── ui/ # UI 组件(shadcn/ui) │ ├── types/ │ │ └── table.ts # 类型定义 │ ├── utils/ │ │ ├── expression.ts # 表达式计算工具 │ │ └── debounce.ts # 防抖工具 │ ├── App.tsx # 示例应用 │ └── main.tsx # 入口文件 ├── package.json ├── vite.config.ts ├── tailwind.config.js └── tsconfig.json
useMemo 缓存计算结果useCallback 避免不必要的重渲染欢迎提交 Issue 和 Pull Request!
MIT License
Made with ❤️ by React Table Plus Team