ReoGrid Web は、Excel グレードの編集体験 — 数式エンジン、xlsx I/O、Canvas レンダラー — をすべて単一の依存ゼロパッケージにまとめた JavaScript/TypeScript 製スプレッドシートライブラリです。React/Vue 用のラッパーと無料の Lite ティアを npm で提供しています。
v1.4 はグリッドを帳票ツールに変えるリリースでした — ページレイアウト、改ページプレビュー、PDF エクスポート、ピボット。v1.5 は「操作」に戻ります。 実際のスプレッドシートを開いて 1 分以内に手が伸びる 2 つ、Ctrl+F とブロックのドラッグ移動が、両エディションに組み込みで入りました。紙側では、Excel と同じ書式コードで書けるページヘッダー/フッターに対応し、PDF エクスポートは自分で CJK フォントを取りに行けるようになりました — ロケールを指定すれば、適切なフォントが埋め込まれます。中国語の出力が豆腐(□□□)になることはもうありません。
その下には、公開 Issue トラッカー由来の修正がまとまって入っています — スクロールするとはみ出しテキストが消える、ドロップダウンが画面外に開く、最終行がスクロールバーの下に隠れる、readReoGridJson が置き換えではなくマージしてしまう、など。
すべて追加的な変更で、公開 API に破壊的変更はありません。
検索と置換 — Lite でも使えます
フォーカスされたグリッドで Ctrl/Cmd+F(検索)または Ctrl/Cmd+H(置換)を押すだけ。準備は以上です。検索バーはシート・現在の選択範囲・ブック全体を対象にでき、ブック全体では一致したシートを自動でアクティブ化するのでカウンタは 2/4 · Sheet1 のように表示されます。オプションは大文字小文字の区別、セル内容が完全に同一、正規表現。一致したセルはすべてキャンバス上でハイライトされ、Enter / Shift+Enter で前後に移動、Escape でクリアします。
置換・全置換は undo 1 手で、保護セルはスキップされます。表示値を対象にした検索(lookIn: 'value')が、結果だけ一致した数式セルを書き換えることはありません。置換は常に生の入力に書き戻すので、数式に対して働く Excel の「置換」と同じ挙動になります。
同じ操作は API からも呼べるので、独自 UI を組むこともできます。
import { createReogrid } from '@reogrid/pro';
// 組み込みバーを無効化して、自前のツールバーに接続する
const grid = createReogrid({ workspace: '#app', showFindBar: false });
const first = grid.find('東京'); // FindMatch | null → { row, column, text }
grid.findNext();
grid.findPrevious();
const all = grid.findAll('東京', { matchCase: true }); // 純粋な読み取り(セッションを開始しない)
const n = grid.replaceAll('東京', '大阪', { wholeCell: true }); // → 変更されたセル数
grid.clearFind();
非表示行・列、結合セルの従属セル、遅延ロードの未ロード行は既定でスキップされます(includeHidden で対象に含められます)。この機能は両エディションで利用可能です — 検索はコピー/貼り付けと同じ基本操作だからです。詳細は検索と置換のドキュメントとデモをご覧ください。
ドラッグで移動 — 範囲・行・列
1 つの操作系に、Excel と同じ 2 つの操作があります。
| 操作 | 内容 | 意味 |
|---|---|---|
| 選択範囲の枠をドラッグ | セルブロックの移動 | 移動先を上書き |
| 選択済みの行・列ヘッダーをドラッグ | 行・列の並べ替え | 切り取り+挿入 — 何も失われない |
選択範囲の枠(内側 ±3px の帯)をつかむとプレビュー矩形がポインタに追随します。右下のフィルハンドルが優先されるため、オートフィルには影響しません。選択済みの行・列ヘッダーを押した場合は 4px 動かして初めて並べ替えが始まるので、単なるクリックはこれまでどおり選択のままです。
セルに保存されているものは一緒に移動します — 値、数式テキスト、リッチテキスト、数値書式、スタイル、セルタイプ、罫線、コメント、ロック状態。
const ws = grid.worksheet;
// ブロックを移動 — 左上が (row, column) に来る。移動先は上書き。
ws.range('A1:C3').moveTo(10, 0);
// 行・列ごと並べ替え(切り取り+挿入)
ws.moveRows(2, 3, 8); // インデックス 2 から 3 行 → インデックス 8 の手前へ
ws.moveColumns(1, 1, 4); // インデックス 1 の 1 列 → インデックス 4 の手前へ
// 事前に判定する
const check = ws.canMoveRange({ topRow: 0, leftColumn: 0, bottomRow: 2, rightColumn: 2 }, 10, 0);
if (!check.ok) console.warn(check.reason);
結合セルを分断する移動、範囲外への移動、保護セルへの移動、遅延ロードのデータソース接続中の移動は拒否されます。しかも拒否理由が読み取れます — onBeforeRangeMove は拒否時も発火し、cancel が立った状態で blockedReason('merge-source' / 'out-of-bounds' / 'protected' など)が渡るので、そのままメッセージにできます。同じイベントはキャンセル可能なので、独自の挙動に差し替えることもできます。
grid.onBeforeRangeMove((event) => {
if (event.kind === 'rows' && event.from.topRow === 0) {
event.cancel = true; // ヘッダー行を固定する
}
});
移動は 1 件の undo エントリになり、worksheet.setRangeMoveEnabled(false) で API を触らずに操作だけ無効化できます。こちらも両エディションで利用可能です。
最初に知っておきたい制限が 2 つあります。v1 では移動したセルを参照している数式は書き換えられません(既存の切り取り/貼り付けと同じ挙動です)。また行・列の並べ替えでは、条件付き書式・入力規則・テーブル・改ページ・アウトライン・フィルターの各範囲は移動しません。詳細は移動のドキュメントとデモをご覧ください。
ページヘッダー・フッター — 紙の余白を、Excel の書式コードで
PrintSettings.headerFooter で用紙の余白にテキストを印刷できます。各帯に左 / 中央 / 右のセクションがあります。
ws.setPrintSettings({
headerFooter: {
header: { center: '売上明細' },
footer: { right: 'ページ &P / &N', left: '&D' },
},
});
セクションのテキストは Excel の書式コードをそのまま保持します — &P(ページ番号、&P+2 のオフセット可)、&N(総ページ数)、&D / &T(日付・時刻)、&F(ファイル名)、&A(シート名)、&Z(パス)、&&(リテラルの &)。そのため Excel を往復しても壊れません。スタイル指定コード(&B、&12、&"Meiryo,Bold"、&KFF0000、&G)は認識したうえで破棄されます(PDF に埋め込むフォントウェイトは 1 種類のため)。未知のコードはそのまま残るので、タイプミスは黙って消えるのではなく目に見えます。
differentOddEven / differentFirst を有効にすると evenHeader / evenFooter、firstHeader / firstFooter の帯が使えます — 綴じ代のある文書の左右振り分けや、ページ番号を出さない表紙に使えます。
帯の位置は margins.header / margins.footer(Excel 既定の 0.3 インチ。従来はハードコードでしたが、実際に反映されるようになりました)。帯が余白より高い場合は本文マージンを押し出すため、セルの上に重ねて印刷されるのではなく 1 ページあたりの行数が減ります。改ページ計算・PDF エクスポート・ページ分割印刷 HTML はすべて同じジオメトリで一致します。saveAsPdf と印刷 HTML の両方が帯を描画し、headerFooter: null を渡せば帯なしで出力できます。xlsx の <headerFooter> と ReoGrid JSON を往復します。
1 点だけ注意があります。画面上の改ページプレビューは帯を描画しません — 枠で示される本文領域が縮むだけです。実際に見るには印刷または PDF 出力してください。Pro 機能です。詳細はページレイアウトのドキュメントをご覧ください。
PDF フォントのロケール指定 — 豆腐の終わり
PDF エンジンはグリフのアウトラインを埋め込むため、エクスポートには常に実際のフォントのバイト列が必要でした。これまで同梱のローダーは loadDefaultJapaneseFont() のみで、これは簡体字中国語のビジネス頻出語の約 35% しかカバーしません。中国語のシートを出力すると豆腐(□□□)だらけになり、サポートされた回避策もありませんでした。
v1.5 でフォントレジストリが入りました。ロケールを指定すれば、ReoGrid が適切なフォントを取得して埋め込みます。
import { createReogrid, preloadPdfFont } from '@reogrid/pro';
const grid = createReogrid({ workspace: '#app' });
await preloadPdfFont('zh-CN'); // 自分で制御できる非同期地点で一度だけ
grid.saveAsPdf({ locale: 'zh-CN', filename: 'report.pdf' });
ja・zh-CN・zh-TW・ko は標準登録済みで、registerPdfFont で独自のフォント(ローダー・URL・手元のバイト列)を追加できます。
なぜ preload を分けているのか。エクスポートを同期のままにするためです。saveAsPdf は最後に生成したリンクをクリックして終わりますが、先に await が挟まるとユーザージェスチャーのコンテキストを失い、ポップアップブロッカーに引っかかります。そこでダウンロードは自分で選んだ地点で一度だけ支払い、以降のエクスポートは即座に完了します。ReoGrid が知らないフォントには従来どおり font でバイト列を渡せます(両方指定した場合は font が優先)。どちらか一方は必須です。
本番では標準の URL に頼らないでください。これはパブリック CDN 上のフルセットフォントを指しています(Noto Sans SC だけで約 17 MB あり、その CDN は中国本土からは低速かつ断続的に到達不能です)。対応するサブセットパッケージをインストールして登録するほうが確実です。バイト列は npm から来るので実行時のネットワークアクセスがゼロになり、企業導入でよくあるオフラインのイントラネットでも動作します。
import { registerPdfFont, preloadPdfFont } from '@reogrid/pro';
import { loadNotoSansSC } from '@reogrid/font-sc'; // ほかに font-tc / font-jp / font-kr
registerPdfFont('zh-CN', loadNotoSansSC);
await preloadPdfFont('zh-CN');
@reogrid/font-sc は GB 2312 全体を含んで転送量 約 2.6 MB — 上流フォントの約 17 MB に対して大幅に軽くなります。Pro 機能です。詳細は PDF エクスポートのドキュメントをご覧ください。
そして Issue トラッカー由来の修正が十数件
多くは実際の報告から来たもので、クラッシュではなく「黙って間違った出力になる」タイプのバグがいくつも含まれています。
- セル自体が画面外にスクロールすると、はみ出しテキストが消えていた問題を修正。 右隣の空セルにはみ出した長い値が、そのセルの列がビューポートから出た途端に丸ごと消えていました。
- ウィンドウ下部のドロップダウンが上方向に開くようになりました。 従来は画面の下端を越えた位置に出てしまい、どうスクロールしても届きませんでした。セルのドロップダウンとオートフィルターのポップアップの両方が対象です。
- フローティング画像がネイティブスクロールバーを覆わなくなり、最終行・最終列がスクロールバーの下に隠れなくなりました(Windows や、常時表示設定の macOS など、領域を占有するスクロールバー環境)。
- ウィンドウ枠の固定後にスクロールバー末尾の無効な遊びが残らなくなりました — 構造変更時にスクロールスペーサーを再計算するようになり、ネイティブとワークシートのスクロール最大値が即座に一致します。
readReoGridJson()がワークシートにマージせず置き換えるようになりました。 2 つ目の文書を読み込んでも前の文書の行・スタイル・結合が下に残りません。またwriteReoGridJson(worksheet)がシート名を保持し、保存のたびにSheet1に戻ることがなくなりました。- 数値書式付きの数式セルが一括再計算後に古い値を表示し続ける問題を修正(ソート・JSON 読み込み・帳票バインド・移動)。
- PDF:
pageSizeの B4 / B5 / Tabloid / Executive が反映されます(従来は無警告で A4 にフォールバック)。JIS B4/B5 は日本の日常的な用紙サイズなので、まさに影響を受けやすいお客様にとって「黙って間違う」バグでした。あわせてグリッド線はシート自身の設定に従い、改ページ境界の罫線が両ページに印刷され、フォントファミリー名を渡した場合(font: 'Arial')はフォントパーサ内部からのRangeErrorではなく、loadFont(url)またはlocaleを案内するメッセージで弾かれます。 worksheet.selectionが公開型定義に含まれるようになりました — ドキュメント記載のファサードは実行時には動作していましたが、同梱の.d.tsから欠落していました。- アウトライングループを解除すると、その行・列が再表示されます。 またグループ括弧の閉じ側の目印が、Excel と同じくトグルボタンから離れた端に描画されるようになりました。
clearRowOutlines()/clearColumnOutlines()ですべてのグループを 1 回で解除できます。
挙動の変更が 2 点あります。列・行の境界のダブルクリックで選択範囲全体が自動調整されるようになりました(A:D を選択していずれかの境界をダブルクリックすると 4 列すべてが調整されます — Excel と同じです)。また HiDPI モニター変更時に再スケールするようになり、Retina と通常モニター間でウィンドウを移動しても、次に手動リサイズするまでキャンバスがぼやけたままになることがなくなりました。
アップグレード
v1.5 はドロップイン更新です — コード変更は不要です。
yarn up @reogrid/pro@latest
Lite は npm で公開、ライセンスキー不要です:
npm install @reogrid/lite
v1.5 の完全な変更履歴はリリースノート、API 全体は検索と置換、範囲・行・列の移動、ページレイアウト、PDF エクスポートの各ドキュメント、体験は検索と置換、範囲移動、PDF 印刷の各デモをご覧ください。Lite / Pro の比較は料金表にあります。