[]
This tutorial will guide you through creating a SpreadJS designer capable of real-time collaboration. Users can edit a workbook in the same room simultaneously, with all changes synchronized across other clients.
As shown in the following figure, all the synchronization operations can be seen.
Create a Project Folder
Create a new folder on your computer, such as spread-collaboration, and navigate into it:
mkdir spread-collaboration
cd spread-collaboration
Initialize a Node.js Project
Run the following command to create a package.json
file:
npm init -y
Edit package.json
and add the following scripts:
{
"name": "spread-collaboration",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node server.js",
"build": "webpack"
},
"dependencies": {}
}
Install Dependencies
Install the npm packages required for the server and client:
npm install @mescius/js-collaboration @mescius/js-collaboration-ot
npm install @mescius/js-collaboration-client @mescius/js-collaboration-ot-client
npm install @mescius/spread-sheets-collaboration @mescius/spread-sheets-collaboration-client
npm install @mescius/spread-sheets @mescius/spread-sheets-collaboration-addon
npm install express
Install npm packages required for the front-end bundling tool:
npm install webpack webpack-cli --save-dev
Use style-loader
and css-loader
:
npm install --save-dev style-loader
npm install --save-dev css-loader
Create a Webpack Configuration File
Create webpack.config.js
in the project root directory with the following content:
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
entry: './public/client.js', // Entry file
output: {
path: path.resolve(__dirname, 'public'), // Output to public directory
filename: 'client.bundle.js' // Output filename
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};
Create the public Directory and Empty Files
Create a public directory and a server.js
file in the project root. Inside the public directory, create index.html
, and styles.css
files. Now the directory structure should look like this:
/ (project root directory)
│── node_modules/ # Dependency modules directory
│── public/ # Public resources directory
│ ├── client.js # Client-side code
│ ├── index.html # Entry HTML file
│── package.json # Project configuration file
│── server.js # Server-side code
│── webpack.config.js # Webpack configuration file
Create the Server
Add the following code to the server.js
file:
import express from 'express';
import http from 'http';
import { Server } from '@mescius/js-collaboration';
import * as OT from '@mescius/js-collaboration-ot';
import { type } from '@mescius/spread-sheets-collaboration';
// Register the type
OT.TypesManager.register(type);
const app = express();
const httpServer = http.createServer(app);
const server = new Server({ httpServer });
const port = 8080;
// Initialize OT document services
const documentServices = new OT.DocumentServices();
server.useFeature(OT.documentFeature(documentServices));
// Initialize OT document services
app.use(express.static('public'));
// Start the server
httpServer.listen(port, () => {
console.log(`Server listening on port ${port}`);
console.log(`http://127.0.0.1:${port}/index.html`);
});
Code Explanation:
Use OT.TypesManager.register to register SpreadJS's type, supporting SpreadJS OT operations.
OT.DocumentServices provides default OT document management functionality.
server.useFeature(OT.documentFeature()) enables OT functionality.
The client will use SpreadJS, js-collaboration-ot-client
, and spread-sheets-collaboration-client
to achieve real-time synchronization.
Write the HTML File (public/index.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SpreadJS Collaboration</title>
<script src="/client.bundle.js"></script>
</head>
<body>
<div id="ss" style="width:100vw;height:95vh;border:1px solid darkgray;float:left"></div>
</body>
</html>
Write the Client JavaScript (public/client.js
)
import * as GC from '@mescius/spread-sheets'
import '@mescius/spread-sheets-collaboration-addon';
import { Client } from "@mescius/js-collaboration-client";
import * as OT from "@mescius/js-collaboration-ot-client";
import { type, bind } from '@mescius/spread-sheets-collaboration-client';
import "@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css";
// Register the type
OT.TypesManager.register(type);
window.onload = async function() {
const workbook = new GC.Spread.Sheets.Workbook('ss');
// Connect to the server and join a room
const conn = new Client().connect('room1');
const doc = new OT.SharedDoc(conn);
// watch error
doc.on('error', (err) => console.error(err));
await doc.fetch();
// Initialize content if the document doesn't exist
if (!doc.type) {
workbook.getActiveSheet().getCell(0, 0).value("default content");
await doc.create(workbook.collaboration.toSnapshot(), type.uri, {});
bind(workbook, doc);
} else {
bind(workbook, doc);
}
}
Code Explanation:
Use OT.SharedDoc to manage the shared document and integrate it with workbook.
Use bind to bind the doc and workbook. For manual binding, refer to SpreadJS Sheets Collaboration packages.
If no doc exists, create it using doc.create.
Bundle the Client Code
npm run build
Start the Server
npm run start
You should see output indicating the server is running at http://localhost:8080.
Test the Functionality
Open a browser and visit http://127.0.0.1:8080/index.html
Open the same address in multiple windows, edit the content, and observe real-time synchronization.
Add persistent storage functionality to SpreadJS designer: Tutorial: Use Database Adapter.
Add real-time display of user presence states (e.g., selection areas) functionality to SpreadJS designer: Tutorial: Use Presence.
Configure specific operational permissions to different users: Tutorial: Use Permissions.