SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

高機能JavaScriptスプレッドシート部品「SpreadJS」の活用(AD)

Excel VBAをWeb化! SpreadJSでスプレッドシート資産を活かすモダナイズ入門

  • X ポスト
  • このエントリーをはてなブックマークに追加

 メシウス株式会社の提供する「SpreadJS」は、サーバサイドの実装を必要とせずにWebブラウザのみでExcelライクなスプレッドシートを作成、表示することのできるJavaScriptライブラリです。本記事では、既存のExcel資産をWebアプリに移行する方法を解説します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

対象読者

  • Excel VBAで作成したマクロをWebアプリに移行したい方
  • JavaScriptを使ってExcelライクな操作を実現したい方
  • SpreadJSを使って業務アプリケーションのUIを改善したい方

SpreadJSとは

 SpreadJSは、JavaScriptだけで動作する高機能なスプレッドシートコンポーネントライブラリです。Webブラウザ上でExcelに近い操作感と豊富な表計算機能を実現し、単なるテーブル表示を超えたインタラクティブなユーザー体験を提供します。

SpreadJSの公式ページ
SpreadJSの公式ページ

 まさに「ExcelをそのままWebに持ち込める」ようなライブラリです。SpreadJSの主な特長は以下の通りです。

  • Excel互換のUI/UX
  • 豊富な関数とセルスタイル
  • 大規模データでも高速レンダリング
  • 豊富な拡張性とAPI

 Excel互換をうたうばかりではなく、「多段ヘッダ」や「ツリー表示」「ガントチャート」など、Excelより高機能な部分もあり、かゆいところに手が届く仕様になっています。

SpreadJSの付加機能の例
SpreadJSの付加機能の例

 今回紹介するExcel VBA資産のWebアプリ移行だけでなく、BIツールに組み込んだり、既存の帳票を活かした業務アプリケーションを構築したりと、さまざまなシーンで利用できます。また、SpreadJSの機能の基本的な使い方については、公式サイトで利用ガイドが公開されているのでそちらもご覧ください。

前提条件

 今回は以下の環境を想定します。SpreadJSの機能だけでなにができるかをわかりやすくするため、フレームワークは使用しませんが、Angular、React、Vue.jsなどとの組み合わせでも利用可能です。

  • 使用言語: JavaScript(Pure JS)
  • SpreadJSのバージョン: 18.0.6
  • 開発環境: Visual Studio Code(以下、「VS Code」)

移行するExcelの紹介と移行の流れ

 本記事で移行対象とするExcelファイルは、店舗ごとの売上データを集計シートにまとめるマクロを搭載したサンプルファイルです。

移行するサンプルのExcelファイル(demo.xlsm)
移行するサンプルのExcelファイル(demo.xlsm)

 サンプルファイルは以下のようなシートから構成されています。

  • 祝日: 集計時に売上対象外とする日付リスト(集計シートの条件付き書式で使用)
  • 集計: 各店舗のデータを読み込み、全店舗の売り上げ合計や平均を計算するシート
  • A店舗B店舗C店舗: 各店舗の日次売上データを表形式で記録するシート

 なお、SpreadJSはマクロつきExcelファイル(demo.xlsm)に非対応のため、以下ではボタンを削除し、Excelファイル(.xlsx)として保存し直したファイル(demo.xlsx)を使用します。

 では、サンプルプロジェクトの構成を確認した上で、SpreadJSの初期化とExcelファイルの読み込みから始めましょう。

サンプルプロジェクトの起動

 以下3つのサンプルプロジェクトを用意しています。

  • samples/: サンプルプロジェクトのルートディレクトリ
    • 01-basic: SpreadJSの初期化とExcelファイルの読み込み
    • 02-with-buttons: HTMLのボタンからSpreadJSのデータを操作
    • 03-with-ribbon: リボンをつけてExcelライクなインターフェースを実現

 実際の動作確認は、VS CodeでLive Serverを起動して行います。VS Codeに拡張機能「Live Server」をインストールし、以下の手順でサンプルプロジェクトを起動します。

  1. プロジェクトのルートディレクトリ(samples)を開く
  2. 任意のindex.htmlを右クリックし、「Open with Live Server」を選択する
  3. ブラウザが起動し、http://localhost:5500/01-basic/のようなURLが表示される

SpreadJSでサーバーに配置したExcelファイルを読み込む

 まずは01-basicプロジェクトで、SpreadJSの初期化とExcelファイルの読み込みまでを見ていきましょう。

プロジェクトのファイル構成

 今回のサンプルは、以下のようなディレクトリ構成になっています。

[リスト1]プロジェクトのファイル構成
samples/
├─ 01-basic/
│  ├─ index.html ← デモアプリのHTMLファイル
│  ├─ css/
│  │   ├─ gc.spread.sheets.18.0.6.css ← SpreadJSメインスタイルシート
│  │   ├─ ...その他のSpreadJS関連スタイルシート
│  │   └─ style.css ← デモアプリ用スタイルシート
│  ├─ scripts/
│  │   ├─ gc.spread.sheets.all.18.0.6.min.js ← SpreadJSメインファイル
│  │   ├─ ...その他のSpreadJS関連ファイル
│  │   └─ index.js ← デモアプリメインスクリプトファイル
│  └─ data/
│      └─ demo.xlsx ← 移行元のExcel VBAサンプルファイル
├─ 02-with-buttons/
│  └── ...
└─ 03-with-ribbon/
   └── ...

 なお、gc.spreadからはじまるファイルは、いずれもSpreadJSのパッケージファイルのSpreadJS_Release/SpreadJS-Libs/SpreadJSフォルダ以下に含まれるファイルをコピーします。ほかにもさまざまなファイルがあるので、必要な機能に応じてコピーして利用してください。

HTMLの準備

 本記事では、Pure JSで実装するため、シンプルなindex.htmlを用意し、必要なCSSやJSファイルを読み込みます。今回はメインのスクリプトをscripts/index.jsに配置するので、そのファイルも読み込みます。

[リスト2]SpreadJSのスクリプトとスタイルシートの読み込み ※ファイル名: 01-basic/index.html
<link rel="stylesheet" href="css/gc.spread.sheets.18.0.6.css" />
<link rel="stylesheet" href="css/gc.spread.sheets.excel2013lightGray.18.0.6.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="scripts/gc.spread.sheets.all.18.0.6.min.js"></script>
<script src="scripts/gc.spread.sheets.io.18.0.6.min.js"></script>
<script src="scripts/gc.spread.sheets.resources.ja.18.0.6.min.js"></script>
<script src="scripts/index.js"></script>

 css/gc.spread.sheets.excel2013lightGray.18.0.6.cssは、Excel 2013のライトグレーのテーマを適用するためのスタイルシートです。これを指定するとSpreadJSの見た目がよりExcelに近くなります。

 scripts/gc.spread.sheets.io.18.0.6.min.jsは、SpreadJSのIO機能を提供するスクリプトで、Excelファイルの読み込みや保存に必要です。

 また、HTMLのbodyには以下のようにid(今回はcontainer)を指定した要素を配置します。この要素にSpreadJSを展開します。

[リスト3]SpreadJS ※ファイル名: 01-basic/index.html
<body>
  <div id="container"></div>
</body>

メインスクリプトの実装

 既存のExcelファイルを読み込むため、以下の流れでSpreadJSを初期化します。

  1. ライセンスキーと言語の設定
  2. new GC.Spread.Sheets.Workbook("container")のようにSpreadJSのWorkbookを初期化
  3. サーバーからExcelファイルをダウンロード(fetchを使用)
  4. workbook.import関数でExcelファイルをSpreadJSにインポート

 実際の初期化部分のソースコードは以下のようになります。

[リスト4]SpreadJSの初期化 ※ファイル名: 01-basic/scripts/index.js
// 1. ライセンスキーと言語の設定
// GC.Spread.Sheets.LicenseKey = "ここにSpreadJSのライセンスキーを設定します";
GC.Spread.Common.CultureManager.culture("ja-jp");
// 2. SpreadJS の Workbook を初期化
const workbook = new GC.Spread.Sheets.Workbook("container");
// 3. サーバーからExcelファイルをダウンロード
const response = await fetch("data/demo.xlsx");
if (!response.ok) {
  throw new Error("Excelファイルの取得に失敗しました");
}
// 4. ExcelファイルをSpreadJSにインポート
workbook.import(
  await response.blob(), // ダウンロードしたExcelファイルをBlobとして渡す
  () => console.log("Excelファイルの読み込みに成功しました"),
  (error) => console.error("Excelファイルの読み込みに失敗しました", error),
  {
    fileType: GC.Spread.Sheets.FileType.excel,
  }
);

 1の部分で、各自が入手したライセンスキーを記述してください。ライセンスキーを設定せずにトライアル版として利用する場合には、コメントアウトしてください。この場合、実行時にトライアル版であることを示すメッセージが表示されます。

実行してみる

 VS CodeのLive Serverを起動し、http://localhost:5500/01-basic/をブラウザで開いてみましょう。Excelファイルが読み込まれ、SpreadJS上にシートが展開されていることが確認できると思います。

SpreadJSで読み込まれたExcelファイル
SpreadJSで読み込まれたExcelファイル

 ここでおもしろいのは「集計」タブのB2やB3セルなど、Excelの計算式が入っているセルがそのまま動作している点です。SpreadJSはExcelの計算式をサポートしているため、計算処理をJavaScriptで独自に実装する必要がありません。

 また、Excelの条件付き書式もそのまま使用できるので、集計シートの2024年10月14日のように、祝日シートに記載されている日付のセル色が動的に変更されていることが確認できます。

条件付き書式によって祝日の列のセル背景色が自動的に設定されている
条件付き書式によって祝日の列のセル背景色が自動的に設定されている

HTMLのボタンからSpreadJSのデータを操作する

 次に、HTML上にボタンを配置し、VBAマクロを実行するのと同じように、SpreadJS上で集計やクリアといった処理を実行できるようにします。サンプルプロジェクト02-with-buttonsを参照してください。

HTMLへのボタン追加

 index.htmlに2つのボタン要素を追加しています。これでもHTMLはとてもシンプルですね。

[リスト5]index.htmlのボタン追加 ※ファイル名: 02-with-buttons/index.html
<body>
  <div id="toolbar">
    <button id="aggregateBtn">集計</button>
    <button id="clearBtn">クリア</button>
  </div>
  <div id="container"></div>
</body>

 http://localhost:5500/02-with-buttons/をブラウザで開くと、2つのボタンが表示されており、クリックすることで、実際に集計シートの内容が変更されることが確認できると思います。

画面上部に表示された集計ボタンとクリアボタン
画面上部に表示された集計ボタンとクリアボタン

「集計」ボタンの実装

 実際の「集計」ボタンの処理を確認しましょう。

  1. 集計シートのB列に、各店舗シート(A店舗B店舗C店舗)の店舗名を記載
  2. 集計シートのC列~AG列に、各店舗シートの売上データを日付ごとにコピー(縦方向に並んだデータを横方向に転記するイメージ)
店舗の売上データコピーのイメージ
店舗の売上データコピーのイメージ

 「集計」ボタンの実装は以下のようになっています。

[リスト6]「集計」ボタンの実装 ※ファイル名: 02-with-buttons/scripts/index.js
function performAggregate() {
  // 集計シートを取得
  const aggregateSheet = workbook.getSheetFromName(aggregateSheetName);
  const aggregateSheetIndex = workbook.getSheetIndex(aggregateSheetName);
  // 店舗シートを取得(集計シートの後のシートを取得)
  const storeSheets = workbook.sheets.slice(aggregateSheetIndex + 1, workbook.sheets.length);
  workbook.suspendPaint(); // 描画を一時停止
  let storeIndex = 0;
  for (const storeSheet of storeSheets) {
    const storeName = storeSheet.name();
    // 店舗名を最初の列にセット
    aggregateSheet.setValue(aggregateRange.row + storeIndex, aggregateRange.col, storeName);
    // 各店舗のシートから日ごとの売り上げの値を集計シートにセット(縦に並んだ数値を横並びにセット)
    for (let dateIndex = 0; dateIndex < 31; dateIndex++) {
      const value = storeSheet.getValue(2 + dateIndex, 1);
      aggregateSheet.setValue(aggregateRange.row + storeIndex, aggregateRange.col + dateIndex + 1, value);
    }
    storeIndex++;
  }
  workbook.resumePaint(); // 描画を再開
}

 ここで使用したSpreadJSのAPIを紹介します。

  • Workbook.getSheetFromName(sheetName): 指定したシート名のシートを取得します。
  • Workbook.getSheetIndex(sheetName): 指定したシート名のシートのインデックスを取得します。
  • Workbook.suspendPaint() / Workbook.resumePaint(): 大量のデータを操作する際に、描画のパフォーマンスを向上させるために使用します。suspendPaintで描画を一時停止し、resumePaintで描画を再開します。
  • Worksheet.setValue(row, col, value): 指定した行・列のセルに値をセットします。
  • Worksheet.getValue(row, col): 指定した行・列のセルの値を取得します。
  • Worksheet.name(): シートの名前を取得します(プロパティではなく関数なので注意してください)

「クリア」ボタンの実装

 「クリア」ボタンでは集計シートの各店舗の売り上げ部分を消去しています。実際の処理は以下のようにWorksheet.clear()関数で、指定した範囲のセルをクリアしているだけです。

[リスト7]「クリア」ボタンの実装 ※ファイル名: 02-with-buttons/scripts/index.js
aggregateSheet.clear(
  aggregateRange.row, // 開始行
  aggregateRange.col, // 開始列
  aggregateRange.rowCount, // 行数
  aggregateRange.colCount, // 列数
  GC.Spread.Sheets.SheetArea.viewport, // 対象エリア
  GC.Spread.Sheets.StorageType.data // ストレージタイプ
);

 GC.Spread.Sheets.SheetArea列挙体では、操作対象のエリアタイプを指定します。今回は 通常のセル範囲を対象とするためSheetArea.viewportを指定しています。

 GC.Spread.Sheets.StorageType列挙体では、操作対象の属性タイプを指定します。今回はセルの値を消去するため、StorageType.dataを指定しています。

 以上で、サーバーから読み込んだExcelデータに対し、HTML上のボタン操作で処理を行うことができました。

リボンをつけてExcelライクなインターフェースを実現する

 SpreadJSでは、リボンをWebアプリに追加することもできます。リボンは、デスクトップ版のMicrosoft Officeでおなじみの、あのUIコンポーネントです。

Microsoft Excelのリボンの例
Microsoft Excelのリボンの例

 さきほど配置したボタンの代わりにリボンを使用して、よりExcelに近い画面にしてみましょう。

リボン関連ファイルの追加

 リボン関連のファイルは、SpreadJSのパッケージファイルのSpreadJS_Release/RibbonContainerフォルダ以下に含まれているので、必要なファイルをscriptsフォルダにコピーしてください。配置例は03-with-ribbonプロジェクトを参考にしてください。

 なお、CSSとJSファイルはribbonという直感的な名前のファイルではなくdesignerという名前になっています。これは、SpreadJSのDesignerと呼ばれる機能を使用してリボンを実現するためです。

リボンつきでSpreadJSを初期化する

 これまでの例ではnew GC.Spread.Sheets.Workbook("container")のようにWorkbookを初期化していましたが、リボンを使用する場合は先にDesignerを初期化します。Designerを初期化した後、getWorkbook()メソッドでWorkbookを取得します。

[リスト8]リボンつきでSpreadJSを初期化する ※ファイル名: 03-with-ribbon/scripts/index.js
// Designer用デフォルト設定を取得
const config = GC.Spread.Sheets.Designer.DefaultConfig;
// 既存タブをすべてクリア
config.ribbon = [
  // リボンのタブ・ボタン設定
];
config.commandMap = {
  // リボンのコマンド設定
};
// Designerを生成(Designerはリボンを実現するためのコンポーネント)
const designer = new GC.Spread.Sheets.Designer.Designer(
  document.getElementById("container"),
  config
);
// Workbookを取得
const workbook = designer.getWorkbook();

 なお、リボンを使う場合は、SpreadJSのライセンスキーのほかにGC.Spread.Sheets.Designer.LicenseKeyに「リボンコンテナ配布用」のライセンスキーを設定する必要があるので注意してください。

 リボンのタブやボタンの設定は、config.ribbonにJSON形式で指定します。そのボタンに対する処理(コマンド)は、config.commandMapに定義します。実際の定義例はサンプルファイルをご確認ください。

 たとえば集計ボタンのコマンドでは以下のように定義し、ボタンが押されたときには元のperformAggregate関数が呼び出されるようにしています。

[リスト9]リボンのコマンド設定 ※ファイル名: 03-with-ribbon/scripts/index.js
cmdAggregateExec: {
  title: "集計シートに店舗の売り上げを転記します",
  text: "集計",
  iconClass: "cmdAggregateExec",
  bigButton: "true",
  commandName: "cmdAggregateExec",
  execute: () => performAggregate(),
},

 実際にLive Serverを起動して、http://localhost:5500/03-with-ribbon/をブラウザで開いてみると、画面上部にリボンが表示され、ボタンを押すと、集計シートの内容が変更されることが確認できると思います。

リボンが表示されたSpreadJS
リボンが表示されたSpreadJS

まとめ

 本記事では、SpreadJSを使用して既存のExcel資産をWebアプリに移行する方法を解説しました。Excelに慣れたユーザーにとっては、操作感を損なうことなく、直感的に利用できるWebアプリが構築できそうです。

 開発者にとっても、Excelの数式や条件付き書式をそのまま使用できるため、複雑なロジックをJavaScriptで実装する必要がなく、開発工数を大きく削減できるでしょう。APIも豊富に用意されており、業務ロジックに合わせたカスタマイズも容易です。

 有料のライブラリですが、ExcelライクなUI/UXを実現するための開発コストを考えれば、リーズナブルに感じます。要件や予算にもよりますが、Excel資産が多い場合や、ユーザーにとってExcelライクな操作が重要な場合は、SpreadJSを検討してみてはいかがでしょうか。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加

提供:メシウス株式会社

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21577 2025/06/16 12:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング