前回の記事では、「神Excel」帳票の見た目を作り直さずWebへ運びました。今回はその先 ― シートを動かします。出勤の☑チェック、勤務区分の選択リスト、稼働率のバー表示。Excelの業務シートが持っているこれらの「操作するUI」を、HTMLフォームを1個ずつ並べ直すことなく、セルの中にそのまま実装します。
セルタイプとは何か
業務シートの多くは、ただ値を表示するだけではありません。クリックして切り替える・選んで入力する・状態をひと目で見る、という操作のためのUIを持っています。
ReoGrid Web のセルタイプは、これをセル単位で実現する仕組みです。チェックボックスやドロップダウンが Canvas 上に直接描画されるため、DOM要素のオーバーレイは発生せず、1万行スクロールしても普通のセルと同じ速度で動きます。
組み込みで8種類が用意されています。
| タイプ | 説明 |
|---|---|
checkbox | チェックボックス(クリックで true / false を切替) |
dropdown | ドロップダウン(選択肢リストから選んだ値がセルに入る) |
button | ボタン(ラベルとクリックハンドラ) |
progress | プログレスバー(数値を可視化) |
rating | 星レーティング(クリックで値変更) |
sparkline-line | 折れ線スパークライン |
sparkline-area | 面スパークライン |
hyperlink | ハイパーリンク(クリックで URL を開く) |
セルタイプは Pro の機能です(料金)。この記事のコードは
@reogrid/proを前提にしています。
基本の使い方
setCellType(行, 列, 設定) でセルにタイプを割り当て、値は通常どおり setCellInput で入れます。引数は 0 始まりの (行, 列) です。
import { createReogrid } from '@reogrid/pro';
const { worksheet } = createReogrid('#grid');
// チェックボックス(値は小文字の 'true' / 'false')
worksheet.setCellType(0, 0, { type: 'checkbox' });
worksheet.setCellInput(0, 0, 'true');
// プログレスバー
worksheet.setCellType(1, 0, { type: 'progress', max: 100, color: '#3b82f6' });
worksheet.setCellInput(1, 0, '75');
// CellHandle でのチェーン記法も使えます
worksheet.cell('A3').setType({ type: 'rating', maxStars: 5 }).setValue('4');
実例:勤怠管理表を組み立てる
日本のオフィスで最も身近な「動くExcel」、勤怠管理表を1週間分つくります。出勤チェック・勤務区分・実働時間・集計・稼働率バーまで、これが完全なコードです。
import { createReogrid } from '@reogrid/pro';
const { worksheet } = createReogrid('#grid');
worksheet.suspendRender(); // まとめて描画(ちらつき防止)
// ── 列構成 ──
worksheet.column('A').width = 110; // 日付
worksheet.column('B').width = 56; // 出勤
worksheet.column('C').width = 110; // 勤務区分
worksheet.column('D').width = 80; // 実働(h)
worksheet.column('E').width = 180; // メモ
// ── タイトル(A1:E1 を結合)──
worksheet.range('A1:E1')
.merge()
.setValue('勤怠管理表(2026年6月 第1週)')
.setStyle({ bold: true, fontSize: 16, textAlign: 'center', verticalAlign: 'middle', color: '#1e3a5f' });
worksheet.row(0).height = 40;
// ── ヘッダー(3行目)──
['日付', '出勤', '勤務区分', '実働(h)', 'メモ'].forEach((h, c) => {
worksheet.cell(2, c).setValue(h);
});
worksheet.range('A3:E3').setStyle({ bold: true, textAlign: 'center', backgroundColor: '#eef2f7', color: '#1e3a5f' });
// ── 明細(6/1 月〜6/7 日)──
const days = [
{ date: '6月1日(月)', weekend: false },
{ date: '6月2日(火)', weekend: false },
{ date: '6月3日(水)', weekend: false },
{ date: '6月4日(木)', weekend: false },
{ date: '6月5日(金)', weekend: false },
{ date: '6月6日(土)', weekend: true },
{ date: '6月7日(日)', weekend: true },
];
days.forEach((d, i) => {
const r = 3 + i; // 0始まりの行 3〜9 = A1形式の行 4〜10
worksheet.cell(r, 0).setValue(d.date);
// 出勤チェックボックス
worksheet.setCellType(r, 1, { type: 'checkbox' });
worksheet.setCellInput(r, 1, d.weekend ? 'false' : 'true');
worksheet.cell(r, 1).setStyle({ textAlign: 'center' });
// 勤務区分ドロップダウン(選んだ値がそのままセルに入る)
worksheet.setCellType(r, 2, {
type: 'dropdown',
options: ['出勤', '在宅', '休暇', '休日'],
});
worksheet.setCellInput(r, 2, d.weekend ? '休日' : '出勤');
// 実働時間
worksheet.setCellInput(r, 3, d.weekend ? '0' : '8');
// 土日の行に色を付ける
if (d.weekend) {
worksheet.range(r, 0, r, 4).setStyle({ backgroundColor: '#fdf2f4' });
}
});
worksheet.range('A4:E10').border({ style: 'solid', color: '#cbd5e1' });
// ── 集計 ──
worksheet.cell('A12').setValue('出勤日数').setStyle({ bold: true });
worksheet.setCellInput(11, 1, '=COUNTIF(C4:C10,"出勤")+COUNTIF(C4:C10,"在宅")');
worksheet.cell('A13').setValue('実働合計').setStyle({ bold: true });
worksheet.setCellInput(12, 1, '=SUM(D4:D10)');
// ── 稼働率バー(数式駆動のプログレスバー)──
worksheet.cell('A14').setValue('稼働率(週40h)').setStyle({ bold: true });
worksheet.range('B14:E14').merge(); // 結合してバーを幅広に
worksheet.setCellType(13, 1, { type: 'progress', max: 100, color: '#3b82f6' });
worksheet.setCellInput(13, 1, '=SUM(D4:D10)/40*100');
worksheet.resumeRender();
ポイントをいくつか。
- チェックボックスの値は小文字の
'true'/'false'です。クリックで自動的に切り替わり、ボックスの領域だけが反応するので、行の選択やコピーは普段どおりできます。 - ドロップダウンはセル右端の▼ボタンをクリックすると選択肢が開き、選んだ値がセルへ書き込まれます。セルの値はただのテキストなので、
COUNTIF(C4:C10,"出勤")のように数式からそのまま集計できます。 - プログレスバーの値には数式が使えます。バーは計算後の表示値を描画するため、実働時間を編集すると稼働率バーがリアルタイムに伸び縮みします。
- セルタイプは結合セルにも適用できます。
B14:E14を結合してからタイプを設定すると、バーが結合範囲いっぱいに描画されます。
編集に反応する ― イベント連携
チェックを切り替えた瞬間にサーバーへ保存したい、画面の別の場所に集計を出したい ― そんなときは onCellValueChange を購読します。チェックボックスの切替もドロップダウンの選択も、通常のセル編集と同じイベントとして届きます。
const off = worksheet.onCellValueChange(({ row, column, value }) => {
if (column === 1) {
// 出勤チェックが切り替わった(value は 'true' / 'false')
console.log(`${worksheet.getDisplayText(row, 0)} の出勤: ${value}`);
}
if (column === 3) {
// 実働時間が編集された → 計算済みの合計を読み出す
const total = worksheet.getDisplayText(12, 1); // B13 = 実働合計
console.log(`実働合計: ${total}h`);
}
});
// 不要になったら購読解除(戻り値が解除関数)
off();
数式セルの計算結果を読むときは getDisplayText(row, col)(書式適用後のテキスト)か getCellNumericValue(row, col)(数値)を使います。cell(...).value は生の入力値を返すため、数式セルでは =SUM(...) という文字列になる点に注意してください。
ダッシュボードに効く残りの4種
勤怠管理表では使いませんでしたが、進捗ダッシュボードやタスク一覧で活躍するタイプたちです。
// 星レーティング(クリックで変更可能)
worksheet.setCellType(0, 0, { type: 'rating', maxStars: 5 });
worksheet.setCellInput(0, 0, '4');
// スパークライン(値はカンマ区切りの数値リスト)
worksheet.setCellType(1, 0, { type: 'sparkline-area', color: '#3b82f6', fillColor: 'rgba(59,130,246,0.2)' });
worksheet.setCellInput(1, 0, '10,20,15,30,25,35');
// ハイパーリンク(「表示テキスト|URL」形式)
worksheet.setCellType(2, 0, { type: 'hyperlink' });
worksheet.setCellInput(2, 0, '社内ポータル|https://example.com');
// ボタン
worksheet.setCellType(3, 0, {
type: 'button',
label: '申請',
onClick: () => { /* 申請処理 */ },
});
8種で足りなければ、CellTypeHandler インターフェースを実装して独自のセルタイプを登録することもできます(Canvas に直接描画するので、信号機・ステータスバッジなど自由自在です)。詳細はセルタイプのドキュメントへ。
Lite と Pro の境界
| 操作 | Lite(無料) | Pro |
|---|---|---|
| xlsx 読み込み・結合・罫線・表示形式 | ✅ | ✅ |
算術式(=D4*1.25) | ✅ | ✅ |
セルタイプ(setCellType 全種) | — | ✅ |
組み込み関数(SUM・COUNTIF 等) | — | ✅ |
xlsx 書き出し(saveAsXlsx) | — | ✅ |
グリッドの表示・編集・xlsx読み込みは無料の Lite で完結します。セルの中にUIを描くのが Pro の領域です。
まとめ
Excel業務シートの「操作するUI」 ― チェックボックス・ドロップダウン・進捗バー ― は、HTMLフォームに作り直さなくても、セルタイプとしてそのままWebに持ち込めます。値はただのセル値なので、数式で集計でき、onCellValueChange でアプリと繋がります。
セルタイプのデモで8種すべてを触ってみるか、勤怠管理表デモで土日色分け付きの月次シートを確認してください。帳票の「見た目」のWeb化は前回の記事で扱っています。