Svelte框架實(shí)現(xiàn)表格協(xié)同文檔的示例
首先,從框架搭建上,本篇示例采用當(dāng)下流行的前后端分離的開發(fā)方式,前端使用npm作為腳手架搭建Svelte框架。 后端使用Java的SpringBoot作為后端框架。
首先,介紹下在前端Svelte框架下搭建在線表格編輯器。
1、在pageage.json文件中引入相關(guān)資源
"@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",2、然后,集成在線表格編輯器Svelte組件版。在上一篇文章中,我們介紹了如何在Svelte框架中實(shí)現(xiàn)在線表格編輯器。
我們按照此思路新建一個SpreadSheet.svelte文件,寫入基礎(chǔ)在線表格編輯器。
<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>3、協(xié)同文檔可能不止一個,我們需要在頁面上創(chuàng)建一個文檔列表,來允許用戶選擇編輯哪個文檔,所以我們需要創(chuàng)建一個文檔列表頁面OnlineSheets.svelte。在此頁面中,我們要實(shí)現(xiàn)路由跳轉(zhuǎn),和加載文檔數(shù)據(jù)。
這里我們用了svelte-spa-router進(jìn)行路由跳轉(zhuǎn) 與isomorphic-fetch進(jìn)行前后端數(shù)據(jù)傳輸。
<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>以上代碼實(shí)現(xiàn)了文檔列表查看與文檔跳轉(zhuǎn),使用 Open將跳轉(zhuǎn)至前面設(shè)計好的在線表格編輯器中。
至此,前端的相關(guān)內(nèi)容就準(zhǔn)備好了,接下來搭建下后端工作。
后端的準(zhǔn)備工作,首先安裝gradle作為包管理器。當(dāng)然,這里也可以用其他工具來代替,例如maven,或者源生引入jar包的方式將需要用到的jar包引入進(jìn)來。之后創(chuàng)建springboot工程配合搭建gradle引用GCExcel以及后面協(xié)同需要用到的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>
這樣子,我們做了框架的基本環(huán)境搭建,接下來我們介紹下如何搭建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;
}接下來我們訪問下文檔列表頁,從文檔列表頁跳轉(zhuǎn)進(jìn)入文檔,進(jìn)行編輯。


接下來我們需要監(jiān)聽前端發(fā)出的操作。這里因為在線表格編輯器本身將所有用戶可能做的操作全部做了封裝,所以省下了很多的功夫。
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)
});根據(jù)cmd去判斷并且對命令再做一些簡單封裝,之后將封裝過的命令發(fā)到服務(wù)端,之后通過websocket發(fā)同步指令:
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))
}
}當(dāng)協(xié)同端通過websocket接收到請求的時候,使用onmessage方法做同步命令。這里在協(xié)同端執(zhí)行command之前需要先撤銷之前的監(jiān)聽,避免再發(fā)送websocket導(dǎo)致死循環(huán)。在執(zhí)行之后,再次添加監(jiān)聽。
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);
}至此,協(xié)同基礎(chǔ)內(nèi)容搭建結(jié)束,我們來看看編輯單元格內(nèi)容后,發(fā)生了什么吧。
如下圖所示,修改E4單元格內(nèi)容,同時打開控制臺網(wǎng)絡(luò)tab。
將E4單元格數(shù)值2500改為2000,此時觸發(fā)了EditCell事件,同時發(fā)出了交互指令:

此時新建一個窗口,復(fù)制鏈接,查看文檔內(nèi)容已經(jīng)變?yōu)榱?000。
如下動圖所示:

到此這篇關(guān)于Svelte框架實(shí)現(xiàn)表格協(xié)同文檔的示例的文章就介紹到這了,更多相關(guān)Svelte 表格協(xié)同文檔內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過實(shí)例理解javascript中沒有函數(shù)重載的概念
這篇文章主要介紹了通過實(shí)例理解javascript中沒有函數(shù)重載的概念,十分的簡單易懂,需要的朋友可以參考下2015-06-06
JavaScript指定字段排序方法sortFun函數(shù)
這篇文章主要介紹了JavaScript指定字段排序方法sortFun函數(shù),數(shù)組的排序方法是sort,但是它并不支持根據(jù)指定的字段進(jìn)行排序,而sortFun可以根據(jù)指定的字段進(jìn)行排序,需要的朋友可以參考下2023-05-05
封裝html的select標(biāo)簽的js操作實(shí)例
本文將為大家介紹下正如標(biāo)題所示的select操作:清空所有的選項、添加一個選項、根據(jù)值、選中一個選項、根據(jù)下標(biāo),選中一個選項,感興趣的朋友可以參考下哈,希望對大家有所幫助2013-07-07
JavaScript使用循環(huán)和分割來替換和刪除元素實(shí)例
一個JavaScript實(shí)例,使用循環(huán)和分割來替換和刪除元素,很簡單,但很實(shí)用,建議初學(xué)者學(xué)習(xí)下2014-10-10
JavaScript事件學(xué)習(xí)小結(jié)(五)js中事件類型之鼠標(biāo)事件
這篇文章主要介紹了JavaScript事件學(xué)習(xí)小結(jié)(五)js中事件類型之鼠標(biāo)事件的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-06-06
數(shù)據(jù)分析軟件之FineReport教程:[5]參數(shù)界面JS(全)
表格軟件FineReport在設(shè)計報表時經(jīng)常會用到,這篇文章主要介紹數(shù)據(jù)分析軟件之FineReport教程:[5]參數(shù)界面JS,需要的朋友可以參考下2015-08-08

