25 种字段 × 8 大视图:我们做了款Mini版飞书式多维表格
今天很高兴又和大家分享我们的AI创业项目。

花2年时间,我们做了一件「听起来有点疯狂」的事:把多维表格协作平台完整做出来:
表格、看板、甘特图、日历、大屏、表单、文档、思维导图------全部围绕同一份数据,一处修改,多处同步。
技术栈:Next.js 14 + React 18 + TypeScript 5 + PostgreSQL + WebSocket,开箱即用。
开源版地址:github.com/MrXujiang/p...
演示地址:pxcharts.turntip.cn
一、Pxcharts Saas 4.0诞生的背景
故事要从一次真实的项目管理说起。我们团队十几个人,需求、排期、Bug 全都存在一张张 Excel 里。每天早上的日常就是:「谁把表改乱了?」「最新版是哪一份?」「这个文件谁发我一下?」

后来大家陆续用上了商业多维表格产品,体验确实好------但新问题又来了:数据放在别人服务器上,私有化部署贵得离谱,想加个定制字段类型根本不可能。对很多中小企业和独立开发者来说,这是一道绕不过去的坎。
于是我们决定自己动手:做一款功能对标主流商业产品、但可以完全私有化部署的多维表格平台。它不仅仅是一个「能编辑单元格的网页」,而是一个完整的数据协作系统------有字段类型体系、有多视图、有公式、有自动化、有实时协同,最好还有 AI。

折腾了很久,它终于成型了,我们叫它 PxCharts。
二、它是什么:一份数据,八种打开方式

一句话定位:PXCharts 是一个AI原生驱动的多维表格协作平台,让同一份数据在表格、看板、甘特图、日历、画廊、表单、层级、图表八种视图之间自由切换,并支持实时协同、自动化与 AI 能力。
下面展示一下它的多种"形态":
1. 表格视图

2. 画廊视图

3. 任务看板

4. 表单视图

5. 甘特图

6. 日历视图

7. 可视化大屏

三、功能亮点深度分析
3.1 25 种字段类型:从文本到 AI,一张表装下所有业务

字段是多维表格的「原子」。我们在 lib/types.ts 里一口气定义了 25 种字段类型 :文本、多行文本、数字、单选、多选、复选框、日期、图片、附件、链接、富文本、进度,还有进阶的关联(relation)、查找引用(lookup)、汇总(rollup)、公式、AI 字段、人员、评分、货币、电话、邮箱、自动编号、按钮、条码、定位。

业务价值:「按钮字段」点一下就能触发一条自动化规则------比如把状态改成「已完成」并同步推送企微机器人。一个单元格,就是一个业务动作的入口。
3.2 八大视图:同一份数据,换一种看法就是另一个工具

数据只有一份,但看它的方式有八种:表格、看板、甘特图、日历、画廊、表单、层级、图表。项目经理看甘特,运营看看板,财务看图表,外部收集数据用表单视图一键生成填写页------谁也不用维护第二份数据。
业务价值:表格视图底层用了 react-window 虚拟滚动,上万行数据也只渲染屏幕里看得见的那几十行,滚动依然顺滑。
3.3 公式引擎:32 个内置函数,Excel 用户无缝上手

我们手写了一个完整的公式解析引擎(词法分析 → 语法解析 → 求值),内置 32 个函数 :SUM 、AVERAGE 、IF 、CONCATENATE 、DATEDIF......函数命名和 Excel 完全对齐,老用户不用学第二套语法。
业务价值:公式重算做了按行增量计算------编辑一个单元格只重算这一行的公式,不扫全表。优化后 2 万行的表,单次编辑的公式计算耗时从 86ms 降到了 0.006ms。
3.4 自动化引擎:3 种触发 × 7 种动作,表格自己会干活

「当记录创建/更新/按钮点击时,如果满足条件,就执行动作」------这套经典模型我们完整实现了。动作多达 7 种:更新字段、站内通知、Webhook、AI 生成、邮件、企业微信机器人、钉钉机器人。
业务价值:引擎里专门写了一行防死循环逻辑------「自动化要更新的字段值没变化就跳过」,否则「更新字段」动作会触发「记录更新」事件,自己点燃自己。
3.5 实时协同:WebSocket 广播,你改的格子同事秒级看见

协同编辑是 pxcharts 多维表格平台的灵魂。我们基于 ws 库实现了独立的协同服务,与 Next.js 共用同一个 server.js 进程,同源部署零额外运维。单元格编辑、整行增删都会以 patch 消息广播给同房间的所有成员,同时还有 presence 在线状态消息,能看到「谁正在看这张表」。
业务价值:落库不是简单的 UPDATE ,而是 「SELECT ... FOR UPDATE 行锁 + 事务」的原子写------两个人同时改同一张表,谁也不会把谁的修改覆盖掉。
3.6 AI 全家桶:AI 字段、AI 建表、自然语言查询

AI 不是贴上去的装饰,而是长在字段体系里的:新增一个「AI 字段」,写好提示词模板(用 {{字段名}} 引用其他列),整列数据就能批量智能生成------比如根据「客户反馈」列自动产出「情感分析」列。
业务价值:还有两个隐藏技能------一句话生成整张表 (AI 建表,自动推断字段结构)和自然语言查询(输入「帮我筛出上周未完成的订单」,AI 翻译成筛选条件直接执行)。
3.7 32 个行业模板:9 大行业,拿来即用

空表格是最劝退的起点。我们内置了 32 个项目模板,覆盖电商、制造、餐饮、零售、物流、教育、人事、互联网、综合 9 大行业:电商订单管理、生产工单、设备巡检、学员档案、物流运单、招聘管理、财务报销......每个模板自带字段结构和示例数据,点一下就能开工。
业务价值:模板不是「示例截图」,是完整的可运行项目------字段、视图、记录全部真实可编辑。
四、整体架构:一个进程把 REST 和 WebSocket 都扛了

架构上我们做了一个很务实的选择:Next.js 的 REST API 和协同 WebSocket 服务跑在同一个 server.js 进程里 。好处是部署只需要一个端口、一个进程,PM2 一拉就起来,小团队不用碰额外的消息中间件;同时客户端天然同源,不用折腾跨域和 HTTPS 下 ws/wss 的协议适配。
关键选型与理由:Next.js 14 ------前后端一体,116 个 API 路由全部是路由文件即接口;Zustand ------表格这种高频局部更新的状态,轻量 store 比全家桶顺手得多;PostgreSQL + JSONB ------字段结构灵活多变,一行 SELECT 拿全表,中小规模表格零 JOIN;ws------原生轻量的 WebSocket 库,协同广播不需要更重的框架。
五、一次单元格编辑,背后跑了哪 6 步

设计上我们有个小讲究:「先本地、后广播、再落库」的乐观更新。用户敲完回车,自己屏幕上的格子立刻变(步骤 ②),不等网络;与此同时 patch 已经飞向服务端广播给同事(③④⑤),REST 落库(⑥)则在后台完成原子写入并顺路触发自动化规则。体验快,数据也不丢。
六、核心实现拆解:四段代码看门道
6.1 协同广播:房间模型,一个函数搞定
lib/collab-server.ts(简化)
// 广播消息到房间内其他客户端(排除发送者)
function broadcastToRoom(roomId, message, excludeClientId) {
const clientIds = rooms.get(roomId)
if (!clientIds) return // 房间不存在,直接忽略
const messageStr = JSON.stringify(message)
clientIds.forEach((cid) => {
if (cid === excludeClientId) return // 跳过发送者自己
const client = clients.get(cid)
if (client && client.ws.readyState === WebSocket.OPEN) {
client.ws.send(messageStr)
}
})
}
大白话解读:每张表就是一个「房间」,谁打开这张表谁就进房。有人改了数据,服务端把消息挨个发给房间里其他人,唯独跳过发消息的自己------因为他的屏幕在步骤 ② 就已经更新过了。得意细节:消息先 JSON.stringify 一次再循环发送,十几人的房间就省十几次序列化,协同高频场景下这是实打实的 CPU 节省。
6.2 原子写入:FOR UPDATE 行锁,并发改表不打架
lib/db.ts(简化)
export async function atomicMutateTableRecords(tableId, mutate) {
return transaction(async (client) => {
// FOR UPDATE 行锁:同一张表的并发写入只能排队
const res = await client.query(
'SELECT data::text FROM tables WHERE id = 1FORUPDATE′, tableId ) constrecords=JSON.parse(res.rows0.data∣∣′\[\]′) constrecords:nextRecords,result=mutate(records) awaitclient.query( ′UPDATEtablesSETdata=1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
JSON.stringify(nextRecords), tableId
)
return result
})
}
大白话解读:整张表的记录存在一个 JSONB 字段里,读写都特别简单,但「两个人同时写」怎么办?答案是一把行锁:改数据前先把这一行锁住,改完释放,后来的人自动排队。得意细节:「读-改-写」三步全包在一个事务里,中途任何一步失败都会整体回滚,不会出现改了一半的脏数据。写入成功后还会异步打一份备份快照,数据可靠性再加一层。
6.3 公式引擎:32 个函数就是一张字典
lib/formula-engine.ts(简化)
const BUILTIN_FUNCTIONS = {
SUM: (...args) => args.reduce((s, v) => s + Number(v || 0), 0),
IF: (cond, trueValue, falseValue) => cond ? trueValue : falseValue,
DATEDIF: (start, end, unit = 'D') => { /* 日期差:D天/M月/Y年 */ },
// ...共 32 个,命名与 Excel 对齐
}
// 求值时按名字分发(大小写不敏感)
const func = BUILTIN_FUNCTIONSfuncName.toUpperCase()
大白话解读:公式先被拆成词法和语法树,遇到函数调用就查这张「函数字典」。新增一个函数,就是往字典里加一行,扩展成本几乎为零。得意细节:所有函数名统一转大写再查表 ,用户写 sum(...) 还是 SUM(...) 都能跑,和 Excel 的宽容度保持一致。
6.4 自动化引擎:一行 continue 防住死循环
lib/automation-engine.ts(简化)
for (const action of rule.actions) {
if (action.type === 'update_field' && action.fieldId) {
// 防自触发死循环:目标字段当前值已相同则跳过
if (event.recordData?.action.fieldId === action.value) continue
fieldUpdatesaction.fieldId = action.value
}
// send_notification / send_webhook / ai_generate /
// send_email / send_wecom / send_dingtalk ......
}
大白话解读:规则命中后挨个执行动作,最危险的是「更新字段」------它本身又会造成一次记录更新,再次触发自动化。所以执行前先比对:值没变就直接跳过 ,递归的火苗被这一行 continue 掐灭。得意细节:动作清单里还藏着 ai_generate------自动化的一个动作可以是「让大模型写点东西填进字段」,规则和 AI 就这样接上了。
七、应用场景分享

下面站在我们调研的市场需求来和大家分享一下有哪些应用场景可以使用 pxcharts 超级表格:
🛒 电商团队:订单管理表 + 看板视图盯发货状态,自动化把超时未发货订单推到企微群。
🏭 制造工厂:生产工单 + 设备巡检记录,甘特视图排产,巡检异常自动邮件通知维保。
🚚 物流公司:运单跟踪表,表单视图给司机上报异常,层级视图看区域-线路-单号。
🧑💼 人事部门:招聘管理流水线,看板拖拽候选人阶段,AI 字段自动总结简历亮点。
🏫 教培机构:学员档案 + 课程排期日历视图,课时消耗用公式字段自动计算。
💻 研发团队:需求池 + Bug 跟踪,图表视图看迭代燃尽,自然语言查询「上周我名下未完成的需求」。
📊 数据敏感型企业:整套系统私有化部署在自己服务器,数据不出内网------这是商业 SaaS 给不了的。
八、写在最后
PXCharts 还在快速迭代中,字段体系、视图、自动化都会继续长。如果大家也有类似的需求和痛点,或者想要一个数据完全握在自己手里的多维表格,欢迎参考我们的方案:
开源版地址:github.com/MrXujiang/p...
觉得有用的话,给我们点个 Star,这就是最大的鼓励!
让数据协作这件事,回到它本该有的样子------简单、实时、可控。
我们下期见!