【实践篇】从零到一:手把手教你搭建一套企业级 SpreadJS 协同设计器

在过去的五篇文章中,我们从宏观价值聊到了底层算法(OT),从视觉感知(Presence)聊到了性能优化(Fragments)与安全管控。相信你已经对 SpreadJS 协同插件的强大能力有了深厚的理论积淀。

然而,"纸上得来终觉浅,绝知此事要躬行"。对于企业级开发者而言,最关心的是:如何将这些模块串联起来,构建出一个生产可用的协作平台?

作为本系列文章的收官之作,我们将回归代码实战。通过一个"从零到一"的完整路径,带你搭建一套集成多人协作、光标同步、数据持久化及权限管理的企业级 SpreadJS 协同设计器。

一、 准备工作:环境与依赖

在开始之前,请确保你的开发环境已安装 Node.js v16+。

我们需要构建两个端:

  1. 服务端(Server):负责分发消息、处理 OT 冲突和持久化数据。
  2. 客户端(Client) :即用户浏览器端的 SpreadJS 编辑器。

1. 初始化项目

Bash 复制代码
mkdir spread-collaboration-demo
cd spread-collaboration-demo
npm init -y

2. 安装核心依赖包

SpreadJS 协同采用了模块化设计,我们需要安装以下关键包:

  • @grapecity-software/js-collaboration: 协同服务器核心。
  • @grapecity-software/js-collaboration-ot: OT 冲突处理模块。
  • @grapecity-software/spread-sheets-collaboration: SpreadJS 专用 OT 类型。
  • @grapecity-software/js-collaboration-presence: 在线状态广播。
  • @grapecity-software/js-collaboration-ot-sqlite: 用于演示的数据持久化适配器(生产环境建议用 Postgres)。

二、 第一步:搭建"大脑"------协同服务器

服务端不仅是消息的中转站,更是数据的"真理来源"。

1. 初始化协同服务器

在项目根目录创建 server.js。我们需要注册 SpreadJS 专用的 OT 类型,这样服务器才能理解表格的"插入行"或"设置公式"等语义。

JavaScript 复制代码
import { Server } from "@grapecity-software/js-collaboration";
import * as OT from "@grapecity-software/js-collaboration-ot";
import { type } from "@grapecity-software/spread-sheets-collaboration"; // 引入 SpreadJS 专用 OT 类型

// 1. 注册 SpreadJS 协同类型
OT.TypesManager.register(type);

// 2. 创建协同服务器实例(支持集成到现有的 Express 或 http 服务)
const server = new Server({ port: 8080 });

// 3. 初始化 OT 文档服务(启用文档同步能力)
server.useFeature(OT.documentFeature());

console.log("协同服务器已在 8080 端口启动...");

2. 配置数据持久化

为了确保协同数据在服务器重启后不丢失,我们需要配置数据库适配器。

JavaScript 复制代码
import sqlite3 from "sqlite3";
import { SqliteDb } from "@grapecity-software/js-collaboration-ot-sqlite";

const db = new sqlite3.Database("./collab_data.db");
const sqliteDbAdapter = new SqliteDb(db);

// 初始化 DocumentServices 时传入数据库适配器
const documentServices = new OT.DocumentServices({ db: sqliteDbAdapter });
server.useFeature(OT.documentFeature(documentServices));

三、 第二步:搭建"视窗"------客户端编辑器

客户端的核心任务是:初始化 SpreadJS,并将其与协同服务器建立连接。

1. 建立连接与文档初始化

在客户端代码中,我们通过 Client 类连接服务器,并使用 SharedDoc 管理共享文档。

JavaScript 复制代码
import { Client } from "@grapecity-software/js-collaboration-client";
import { SharedDoc } from "@grapecity-software/js-collaboration-ot-client";
import { type, bind } from "@grapecity-software/spread-sheets-collaboration-client";

// 1. 连接服务器并加入指定房间
const connection = new Client("ws://localhost:8080").connect("room-001");

// 2. 创建共享文档实例并获取数据
const doc = new SharedDoc(connection);
await doc.fetch(); 

// 3. 如果是新文档,则初始化内容
if (!doc.type) {
    await doc.create(workbook.collaboration.toSnapshot(), type.uri);
}

// 4. 核心步骤:将 SpreadJS Workbook 与 共享文档 绑定
// bind 方法会全自动处理:监听本地操作提交 -> 接收远程操作应用
bind(workbook, doc);

2. 启用 Presence(光标与选区同步)

为了让协作"看得见",我们需要启用 Presence 插件。

JavaScript 复制代码
import { Presence } from "@grapecity-software/js-collaboration-presence-client";
import { bindPresence } from "@grapecity-software/spread-sheets-collaboration-client";

const presence = new Presence(connection);
const currentUser = { id: "user_A", name: "张三", color: "#FF0000" };

// 将用户信息与 Workbook 绑定,实现光标实时显示
await bindPresence(workbook, presence, currentUser);

四、 第三步:安全管控与权限注入

正如第五篇文章所说,企业应用必须有权限控制。我们在客户端设置用户的浏览模式,并在服务端进行二次校验。

1. 客户端权限设置

JavaScript 复制代码
const userWithPermission = {
    ...currentUser,
    permission: {
        mode: GC.Spread.Sheets.Collaboration.BrowsingMode.view, // 设置为查看模式
        viewModePermissions: GC.Spread.Sheets.Collaboration.PermissionTypes.allowFilter | 
                             GC.Spread.Sheets.Collaboration.PermissionTypes.allowSort
    }
};
workbook.collaboration.setUser(userWithPermission);

2. 服务端中间件审计

在 server.js 中增加审计逻辑,拦截未授权的修改请求。

JavaScript 复制代码
// 验证每一笔提交的操作
documentServices.use('submit', async (context, next) => {
    const userInfo = context.connection.tags.get('user');
    if (userInfo.mode === 'viewer') {
        return await next(new Error('只读用户禁止提交修改!')); 
    }
    await next();
});

五、 核心要点:V19 版本授权激活

SpreadJS V19 对协同插件引入了更严格的双重授权机制。这是生产环境部署最关键的一步,请务必关注:

  1. 获取机器 ID:在目标服务器上运行以下代码:

    JavaScript 复制代码
       import { getMachineIdForServerLicense } from '@grapecity-software/js-collaboration';
       console.log(getMachineIdForServerLicense());
  2. 申请 Server Key :将机器 ID 与你的 SpreadJS 部署授权(License Key)提交给支持团队,换取 serverLicenseKey。

  3. 配置激活:

    JavaScript 复制代码
      const server = new Server({ httpServer });
      server.licenseKey = "你的部署授权Key";
      server.serverLicenseKey = "你的服务器授权Key";

    注:若未配置授权,服务器将仅允许 localhost 访问,非本地请求将被拒绝。

六、 总结:开启你的协作时代

通过以上四步,我们已经成功搭建了一个具备实时同步、冲突处理、视觉感知、持久化存储和安全审计能力的 Web Excel 协作中台。

回顾整个系列:

  • 我们从价值出发,理解了协同对企业效率的革命性意义;
  • 我们深入技术,拆解了 OT 算法、Presence 模块和片段机制;
  • 最后,我们回归实践,展示了 SpreadJS 协同插件如何以高度封装的 API 降低开发门槛。

SpreadJS 协同插件(Collaboration Add-on)不仅是一个功能,它是一整套成熟的、可扩展的实时协作解决方案。它让复杂的表格业务不再受制于空间的距离,让数据在流转中产生真正的价值。

即刻开始你的协同之旅吧! 如果你在实践中遇到任何问题,欢迎访问我们的官方技术社区进行交流。

系列文章回顾:

  1. 【趋势篇】告别"文件传阅",企业级在线协同的全景视野
  2. 技术本质篇深度解析 OT 算法:解决冲突的终极方案
  3. 【体验篇】Presence 插件:打造零距离的团队临场感
  4. 【性能优化篇】片段机制:支撑海量数据的协作底座
  5. 安全管控篇细粒度权限与版本追溯的完美平衡
  6. 【实践篇】从零到一:手把手搭建你的协作中台(本篇)
相关推荐
鬼手点金8 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
蛋蛋的就会顺顺的8 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday9 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室9 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
码艺-Alimjan9 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床9 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a11 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台11 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
pride.li12 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
屏什么录12 小时前
电脑如何录屏幕视频和声音?从工具到代码,7 种方案帮你彻底搞定
前端·音视频开发