2026年7月23日にリリースされた「SpreadJS(スプレッドJS)」のバージョン「V19.1J」では、Excelのように複数のユーザーで同じワークブックを同時に編集できる「共同編集機能」が追加されました。これによりチームでのデータ編集や確認を同一画面でリアルタイムに実施できます。
※ 共同編集機能を組み込んだアプリケーションを配布するには「配布ライセンス共同編集機能アドオン」が必要です。このライセンスを設定しない場合、トライアル版を示すメッセージが表示されます。ライセンスの詳細はこちらをご覧ください。
本記事では、SpreadJSの共同編集機能の概要や特長、実装方法について詳しく解説いたします。
SpreadJSの共同編集機能の概要
SpreadJSの共同編集機能の特長
SpreadJSの共同編集機能には、次のような特長があります。
同時編集と編集内容のリアルタイムな反映
複数のユーザーで同じワークブックを同時に編集し、その編集内容を他のユーザーの画面にリアルタイムに反映できます。
各ユーザーの編集状態の表示
他ユーザーの選択範囲や選択中のセルをリアルタイムに表示できます。誰がどこを編集しているのかを視覚的に把握できるため、作業状況を共有しながら効率的に編集を進められます。また、他ユーザーの編集内容に加えて作業位置も確認できるため、編集の重複や意図しない競合を抑えやすくなります。
ユーザーの権限設定
共同編集機能を使用する各ユーザーに対して「シートの編集が可能」、「シートの閲覧のみ可能」といった権限設定が可能です。役割に応じた柔軟な権限管理により、チームでの共同作業をより安全に進めることができます。
スレッド形式のコメントをリアルタイムに表示
共同編集機能とスレッド形式のコメントを併用することで、シート上でリアルタイムに内容の確認や調整を行いながら編集を進めることができます。スレッド形式のコメントについては、以下の記事もご参照いただければと思います。
共同編集機能のアーキテクチャ
SpreadJSの共同編集機能は、下記のコアモジュールによって提供されています。
- js-collaboration
- js-collaboration-ot
- js-collaboration-presence
これらのモジュールで構成されるフレームワークは、下図のように標準的なクライアント・サーバーアーキテクチャを採用しています。

以下に、各モジュールの概要を説明します。
js-collaboration
js-collaborationは、WebSocketによるリアルタイムのデータ同期を提供し、クライアントとサーバー間の双方向通信を可能にします。具体的には、次のような機能を実装しています。
- 双方向通信
- クライアントとサーバー間の双方向メッセージ送信をサポートします。
- ルーム管理
- 分離されたルームにより、複数ユーザーによる複数の共同作業を可能にします。
- ブロードキャスト
- 同じルーム内でメッセージをブロードキャスト(リアルタイム通知)します。
- 自動再接続
- 接続切断時に、ハートビート検出と自動再接続を行います。
- ミドルウェアとフック
- 接続とメッセージ処理にユーザー定義のカスタムロジックを挿入できるようにします。
js-collaborationは、次の2つのnpmパッケージとしてカプセル化されています。
- サーバー用パッケージ
- @mescius/js-collaboration
- クライアント用パッケージ
- @mescius/js-collaboration-client
js-collaboration-ot
js-collaboration-otは、操作変換(OT:Operational Transformation)技術に基づいており、複数ユーザーによる同時編集操作を可能にします。具体的には次のような機能を実装しています。
- カスタムOTタイプ
- 多様な要件に対応するために独自の操作タイプを定義できます。
- データ永続化
- ストレージと統合するためのアダプターインターフェイスを提供します。
- フラグメント機構
- 大規模ドキュメントに対する同期パフォーマンスを向上させます。
- 競合解決
- OTアルゴリズムによりデータ整合性を確保します。
- ミドルウェアとフック
- 共同編集の処理に検証やログ記録などのロジックを挿入できるようにします。
js-collaboration-otは、次の2つのnpmパッケージとしてカプセル化されています。
- サーバー用パッケージ
- @mescius/js-collaboration-ot
- クライアント用パッケージ
- @mescius/js-collaboration-ot-client
また、データ永続化のために次のデータベースアダプターが提供されています。
- PostgreSQL用アダプター
- @mescius/js-collaboration-ot-postgres
- SQLite3用アダプター
- @mescius/js-collaboration-ot-sqlite
js-collaboration-presence
js-collaboration-presenceは、他ユーザーが選択しているセルやセル範囲をリアルタイムに表示し、誰がどこを編集しているのかを可視化します。具体的には次のような機能を実装しています。
- リアルタイムのユーザー状態共有:各ユーザーの現在のセル位置や選択されたセル範囲を表示します。
- イベント監視:ユーザーの参加/退出やその他の状態更新を監視します。
js-collaboration-presenceは、次の2つのnpmパッケージとしてカプセル化されています。
- サーバー用パッケージ
- @mescius/js-collaboration-presence
- クライアント用パッケージ
- @mescius/js-collaboration-presence-client
共同編集機能の使い方
今回はクイックスタートとして、共同編集機能の基本部分だけを実装し、js-collaboration-presenceが提供する他ユーザーのセル位置や選択範囲を共有する機能は省いています。
プロジェクトのファイル構成
作成するプロジェクトのファイル構成(インストールやバンドルによって自動生成されるものを除く)は次のとおりです。バックエンドを構成するファイルはプロジェクトのルートに置き、フロントエンドを構成するものは「public」フォルダ内に配置します。
project/
├── server.js # サーバー側のコード
├── package.json # プロジェクト設定ファイル
├── webpack.config.js # Webpack設定ファイル
└── public/ # 公開リソース用ディレクトリ
├── client.js # クライアント側のコード(index.html用)
├── container.js # クライアント側のコード(iframe.html用)
├── iframe.html # エントリーポイントとなるHTML
└── index.html # SpreadJSを配置するHTMLプロジェクトの作成
このプロジェクトでは、SpreadJSを配置している2つのHTMLを1つのページに組み込むことで、このページだけで共同編集機能を試せるようにしています。
それでは、下記の手順に従って基本的な共同編集機能を実装したプロジェクトを作成しましょう。
プロジェクトの初期化
プロジェクトフォルダの作成
新しいフォルダ(この例ではspreadjs-collaboration)を作成し、そのフォルダに移動します。
mkdir spreadjs-collaboration
cd spreadjs-collaborationNode.jsプロジェクトの初期化
次のコマンドを実行してpackage.jsonファイルを作成します。
npm init -y生成されたpackage.jsonファイルを下記のように編集します。
{
"name": "spreadjs-collaboration",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node server.js",
"build": "webpack"
},
"dependencies": {}
}npmパッケージのインストール
SpreadJSのnpmパッケージをインストールします。ここでは共同編集機能が導入されたバージョン「19.1.5」を指定していますが、ご利用のバージョンに合わせて変更してください。
npm install @mescius/js-collaboration@19.1.5
npm install @mescius/js-collaboration-ot@19.1.5
npm install @mescius/js-collaboration-client@19.1.5
npm install @mescius/js-collaboration-ot-client@19.1.5
npm install @mescius/spread-sheets-collaboration@19.1.5
npm install @mescius/spread-sheets-collaboration-client@19.1.5
npm install @mescius/spread-sheets@19.1.5
npm install @mescius/spread-sheets-collaboration-addon@19.1.5
npm install @mescius/spread-sheets-resources-ja@19.1.5その他のnpmパッケージとローダーをインストールします。
npm install express
npm install webpack webpack-cli --save-dev
npm install --save-dev style-loader
npm install --save-dev css-loaderWebpack設定ファイルの作成
プロジェクトのルートディレクトリにwebpack.config.jsファイルを作成し、次の内容を記述します。
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
entry: {
index: './public/client.js',
iframe: './public/container.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public'),
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};フォルダとファイル(内容は未記載)の作成
プロジェクトのルートディレクトリに下記のフォルダとファイルを作成します。
- publicフォルダ
- server.jsファイル
作成したpublicフォルダ内に下記のファイルを作成します。
- client.js
- container.js
- iframe.html
- index.html
サーバーのセットアップ
先ほど作成したserver.jsファイルに次のコードを記述します。
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';
// typeを登録
OT.TypesManager.register(type);
const app = express();
const httpServer = http.createServer(app);
const server = new Server({ httpServer });
const port = 8080;
// ライセンスの設定
server.LicenseKey = 'localhost環境以外では、ここにSpreadJSの共同編集機能が有効なサーバー用ライセンスキーを設定します';
// OTドキュメントサービスを初期化
const documentServices = new OT.DocumentServices();
server.useFeature(OT.documentFeature(documentServices));
// publicディレクトリを静的リソースとして公開
app.use(express.static('public'));
// サーバーを起動
httpServer.listen(port, () => {
console.log(`Server listening on port ${port}`);
console.log(`http://127.0.0.1:${port}/iframe.html`);
});※ localhost環境以外では、共同編集機能が有効なサーバー用ライセンスキー(配布ライセンス共同編集機能アドオンが適用されたもの)を設定しない場合、ライセンス情報がないことなどを示すメッセージが表示されます。
上記の「OT.TypesManager.register(type);」は、spread-sheets-collaborationのtype(OT_Type)を登録します。これにより、SpreadJSでOTオペレーションが利用できるようになります。
「const documentServices = new OT.DocumentServices();」は、既定のOTドキュメント管理機能を利用できるようにします。
最後に、「server.useFeature(OT.documentFeature(documentServices));」によってOT機能が有効になります。
サーバーの初期化については、ヘルプもご一読いただければと思います。
クライアントのセットアップ
クライアント側ではSpreadJS、js-collaboration-ot-client、およびspread-sheets-collaboration-clientを使用してリアルタイム同期を実現します。
クライアントを構成する次のファイルに下記のコードを記述します。
- iframe.html(エントリーポイントとなるHTML)
- index.html(SpreadJSを配置するHTML)
- container.js(iframe.html用コード)
- client.js(index.html用コード)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SpreadJSの共同編集機能</title>
<script src="iframe.js"></script>
<style>
iframe {
border: 1px solid silver;
}
</style>
</head>
<body>
<iframe id="iframe1" src="index.html" width=600 height=500></iframe>
<iframe id="iframe2" src="index.html" width=600 height=500></iframe>
</body>
</html>iframeタグを使って2つのindex.htmlを組み込んで、共同編集機能の動作を1つのページで確認できるようにします。ここで参照しているiframe.jsファイルは、バンドルを実行したときに自動的に生成されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="index.js"></script>
</head>
<body>
<div id="ss" style="width:95vw;height:95vh;border:1px solid silver;"></div>
</body>
</html>SpreadJSを配置したHTMLです。iframe.html上に2つ組み込まれます。ここで参照しているindex.jsファイルは、バンドルを実行したときに自動的に生成されます。
window.onload = () => {
// iframeのリロード
window.setTimeout(() => {
const iframe1 = document.getElementById('iframe1');
iframe1.contentWindow.location.reload();
const iframe2 = document.getElementById('iframe2');
iframe2.contentWindow.location.reload();
}, 500);
}iframe.htmlがロードされたときに各iframeを更新し、index.htmlが参照するindex.jsが適切に実行されるようにします。
import * as GC from '@mescius/spread-sheets'
import '@mescius/spread-sheets-resources-ja';
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";
// ライセンスの設定
GC.Spread.Sheets.LicenseKey = 'ここにSpreadJSの共同編集機能が有効なライセンスキーを設定します';
// typeを登録
OT.TypesManager.register(type);
window.onload = async () => {
// ワークブックの生成
const workbook = new GC.Spread.Sheets.Workbook('ss');
// カルチャの設定
GC.Spread.Common.CultureManager.culture('ja-jp');
// サーバーに接続し、ルームに参加
const conn = new Client().connect('room1');
const doc = new OT.SharedDoc(conn);
// エラー監視
doc.on('error', (err) => console.error(err));
await doc.fetch();
// ドキュメントが存在しない場合は初期化
if (!doc.type) {
await doc.create(workbook.collaboration.toSnapshot(), type.uri, {});
bind(workbook, doc);
} else {
bind(workbook, doc);
}
}※ 共同編集機能が有効なライセンスキー(配布ライセンス共同編集機能アドオンが適用されたもの)を設定しない場合、トライアル版を示すメッセージが表示されます。
このコードは、Index.htmlが読み込まれたときに実行されます。
上記の「const doc = new OT.SharedDoc(conn);」により、関連付けられている接続から新しい共有ドキュメントを作成します。
「await doc.create(workbook.collaboration.toSnapshot(), type.uri, {});」は、現時点のworkbookに対応した共有ドキュメントを生成します。
最後に、「bind(workbook, doc);」でworkbookを共有ドキュメントにバインドします。
プロジェクトのビルド
次のコマンドを実行してクライアントコードをバンドルします。
npm run buildこれにより、webpack.config.jsに記載した内容に従って「iframe.js」ファイルと「index.js」ファイルが生成され、ブラウザでiframe.htmlとindex.htmlが読み込まれたときにこれらのコードが実行されます。
共同編集機能の動作確認
以上でプロジェクトが完成したので、次のコマンドを実行してサーバーを起動しましょう。
npm run start続いて、ブラウザを開いて「http://127.0.0.1:8080/iframe.html」にアクセスします。
表示されたiframe.htmlの左側のSpreadJSでセルに値を設定したり、列幅や行高を変更したりすると、右側にあるSpreadJSの対応するセルの値、列幅、行高が同期して変更されます。逆に、右側のSpreadJSで編集した内容はリアルタイムに左側のSpreadJSに反映されます。
今回作成したサンプルは以下よりダウンロード可能です。実際に動かしながら動作を確認したい方はぜひご利用ください。
共同編集機能などの最新機能をウェビナーで解説!
本記事では共同編集機能を最小に使い構成で実装する方法をご紹介しましたが、2026年10月22日(木)開催予定のウェビナーでは、共同編集機能の概要や導入方法、コラボレーションフレームワークの仕組みなどを製品付属サンプルを使ったデモを交えて解説します。
また、先日パブリックプレビューとなったAI駆動開発を支援する「メシウス MCPサーバー」の使用方法についてもご紹介しますので、興味のある方はぜひご参加ください。
さいごに
今回の記事では、SpreadJSの共同編集機能の特長と基本的な利用方法についてご紹介しました。共同編集機能を利用することで、Webアプリケーション上にExcelライクな操作性を提供しながら、リアルタイム同期や編集状態の共有、ユーザーごとの権限設定などを実現できます。また、コラボレーションフレームワークにより大規模な業務アプリケーションにも柔軟に組み込むことが可能です。
製品サイトでは、SpreadJSの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。
また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。
