基于Svelte与SpringBoot实现在线表格协同编辑
本文介绍如何使用Svelte框架结合SpringBoot后端,实现在线表格的协同编辑功能。通过集成SpreadJS组件、配置前后端分离架构,并利用WebSocket实现实时数据同步,展示从环境搭建到单元格内容变更同步的完整流程。
前后端分离架构搭建
本示例采用前后端分离的开发架构。前端基于npm脚手架搭建Svelte框架,后端则选用Java的SpringBoot作为服务支撑。
Svelte在线表格编辑器集成
首先阐述如何在Svelte环境中构建在线表格编辑器。
第一步,在package.json文件中引入必要的依赖资源。
"@grapecity/spread-excelio": "15.2.5",
"@grapecity/spread-sheets": "15.2.5",
"@grapecity/spread-sheets-barcode": "15.2.5",
"@grapecity/spread-sheets-charts": "15.2.5",
"@grapecity/spread-sheets-designer": "15.2.5",
"@grapecity/spread-sheets-designer-resources-cn": "15.2.5",
"@grapecity/spread-sheets-languagepackages": "15.2.5",
"@grapecity/spread-sheets-pdf": "15.2.5",
"@grapecity/spread-sheets-pivot-addon": "15.2.5",
"@grapecity/spread-sheets-pivots": "^14.0.0",
"@grapecity/spread-sheets-print": "15.2.5",
"@grapecity/spread-sheets-resources-zh": "15.2.5",
"@grapecity/spread-sheets-shapes": "15.2.5",
"@grapecity/spread-sheets-tablesheet": "15.2.5",第二步,集成Svelte组件版的在线表格编辑器。参考前文思路,新建SpreadSheet.svelte文件并编写基础表格编辑功能。
<script>
import {onMount} from 'svelte';
import '@grapecity/spread-sheets-print';
import "@grapecity/spread-sheets-charts";
import '@grapecity/spread-sheets-shapes';
import '@grapecity/spread-sheets-pivot-addon';
import '@grapecity/spread-sheets-tablesheet';
import '@grapecity/spread-sheets-designer-resources-cn';
import '@grapecity/spread-sheets-designer';
import * as GC from '@grapecity/spread-sheets';
import * as GCDesigner from '@grapecity/spread-sheets-designer';
let designer = null;
onMount(async () => {
designer = new GCDesigner.Spread.Sheets.Designer.Designer(document.getElementById("designerHost"));
let spread = designer.getWorkbook();
});
</script>
<div id="designerHost" class="designer-host"></div>
<style scoped>
@import "@grapecity/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css";
@import '@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css';
.designer-host {
width: 100%;
height: 100vh;
}
</style>第三步,考虑到协同文档可能包含多个,需在页面创建文档列表以允许用户选择编辑目标。为此创建OnlineSheets.svelte页面,实现路由跳转及文档数据加载。此处使用svelte-spa-router处理路由,并通过isomorphic-fetch进行前后端数据交互。
<script>
import {onMount} from 'svelte';
import { link } from "svelte-spa-router";
import {Utility} from "../utility.js";
let docList = [];
onMount(async () => {
Utility.getDocList().then(result => {
docList = result.map((item,index)=>{
return {
path:'/Spreadsheet/' + item.substring(0, item.lastIndexOf('.')),
index,
fileName:item
}
})
});
});
</script>
<main class="main">
<table className='table' aria-labelledby="tabelLabel">
<thead>
<tr>
<th>Document</th>
<th></th>
</tr>
</thead>
<tbody>
{#each docList as docItem}
<tr>
<td>{docItem.index}</td>
<td>{docItem.fileName}</td>
<td className='row'>
<a use:link={docItem.path}> Open</a>
</td>
</tr>
{/each}
</tbody>
</table>
</main>上述代码完成了文档列表查看与跳转功能,点击“Open”可进入预设的在线表格编辑器。前端准备就绪后,开始搭建后端环境。后端需先安装gradle作为包管理工具(也可选用maven或手动引入jar包)。随后创建SpringBoot工程,并配置gradle以引用GCExcel库及后续协同所需的WebSocket支持。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.grapecity.documents</groupId>
<artifactId>gcexcel</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>10.0.2</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>WebSocket协同通信配置
完成基础框架搭建后,接下来介绍WebSocket的配置。在SpreadSheet.svelte文件中添加代码以建立WebSocket连接。
function connectDocument(docName) {
if (webSocket != null) {
return;
}
var ws = new WebSocket(Utility.webSocketUrl); //'ws://localhost:8090/spreadjs'
ws.onopen = function () {
var data = {
cmd: "connect",
docID: docName
}
ws.send(JSON.stringify(data));
}
ws.onmessage = onmessage;
webSocket = ws;
}随后访问文档列表页,从中跳转进入具体文档进行编辑操作。


接下来需监听前端发出的操作指令。由于在线表格编辑器已封装了所有用户可能的操作,这简化了开发工作。
onMount(async () => {
//初始化Designer
designer = new GCDesigner.Spread.Sheets.Designer.Designer(document.getElementById("designerHost"));
let spread = designer.getWorkbook();
//fromJSON
openDocument(docName);
//建立webSocket
connectDocument(docName);
var cm = spread.commandManager();
cm.addListener('myListener', onCommandExecute)
});根据cmd判断命令类型并进行简单封装,随后将封装后的命令发送至服务端,并通过WebSocket发送同步指令。
function onCommandExecute(args) {
console.log(args.command);
var command = args.command;
var ServerCommand = null;
switch (command.cmd) {
case Utility.ServerCommands.EditCell:
ServerCommand = {
sheetName: command.sheetName,
row: command.row,
column: command.col,
newValue: command.newValue
}
break;
case Utility.ServerCommands.ResizeRow:
ServerCommand = {
sheetName: command.sheetName,
rows: command.rows,
size: command.size
};
break;
case Utility.ServerCommands.ResizeColumn:
ServerCommand = {
sheetName: command.sheetName,
columns: command.columns,
size: command.size
};
break;
case 'Designer.' + Utility.ServerCommands.SetFontFamily:
case 'Designer.' + Utility.ServerCommands.SetFontSize:
case 'Designer.' + Utility.ServerCommands.SetBackColor:
case 'Designer.' + Utility.ServerCommands.SetForeColor:
case 'Designer.' + Utility.ServerCommands.SetFontWeight:
case 'Designer.' + Utility.ServerCommands.SetFontStyle:
case 'Designer.' + Utility.ServerCommands.SetUnderline:
case 'Designer.' + Utility.ServerCommands.SetDoubleUnderline:
if (command.value && command.value.indexOf('undefined') === -1) {
ServerCommand = {
sheetName: command.sheetName,
selections: command.selections,
value: command.value
}
}
break;
case Utility.ServerCommands.MoveFloatingObjects:
ServerCommand = {
sheetName: command.sheetName,
floatingObjects: command.floatingObjects,
offsetX: command.offsetX,
offsetY: command.offsetY
};
break;
case Utility.ServerCommands.ResizeFloatingObjects:
ServerCommand = {
sheetName: command.sheetName,
floatingObjects: command.floatingObjects,
offsetX: command.offsetX,
offsetY: command.offsetY,
offsetWidth: command.offsetWidth,
offsetHeight: command.offsetHeight
};
break;
case Utility.ServerCommands.InsertColumns:
case Utility.ServerCommands.InsertRows:
ServerCommand = {
sheetName: command.sheetName,
selections: command.selections
};
break;
default:
}
if (ServerCommand != null) {
var cmd = command.cmd;
var dotIndex = cmd.lastIndexOf('.');
if (dotIndex !== -1) {
cmd = cmd.substring(dotIndex + 1);
}
ServerCommand.cmd = cmd;
ServerCommand.docID = params.fileName;
Utility.ExecuteCommandAtServer(ServerCommand);
command.docID = ServerCommand.docID;
webSocket.send(JSON.stringify(command))
}
}当协同端通过WebSocket接收到请求时,使用onmessage方法执行同步命令。在执行command前需先撤销之前的监听,以避免因再次发送WebSocket消息导致死循环。执行完毕后,重新添加监听器。
function onmessage(message) {
var command = JSON.parse(message.data);
command._styles = null;
let spread = designer.getWorkbook()
var cm = spread.commandManager();
cm.removeListener('myListener');
spread.commandManager().execute(command);
cm.addListener('myListener', onCommandExecute);
}协同编辑效果验证
协同基础内容搭建完毕,接下来观察编辑单元格内容后的变化。如图所示,修改E4单元格内容并打开控制台网络标签页。将E4单元格的数值从2500改为2000,此时触发EditCell事件,并发出相应的交互指令。

此时新建窗口并复制链接,查看文档内容已更新为2000。具体效果如下动图所示。

至此,关于Svelte框架实现表格协同文档的示例介绍完毕。如需了解更多Svelte表格协同文档相关内容,可搜索本站历史文章或继续浏览后续文章,感谢支持。
JS 怎么使用 pako.js 解压 gzip 数据流
2026-11-05 15:54:33
零基础先学JavaScript还是Python?对比学习难度与上手曲线
2026-11-05 14:47:40
JS代码反混淆:主流在线工具与本地软件推荐
2026-11-04 19:28:41
浏览器控制台查看格式化JSON有哪些实用技巧
2026-11-04 16:56:53
JS控制台打印基础:console.log语法与多参数用法
2026-11-04 09:23:11
