Luckysheetは、Excelのような表計算画面をブラウザだけで動かすオープンソースのJavaScriptライブラリです。ただし2026年11月2日にnpm registryで確認した最新版は、2021年1月19日公開の2.1.13のままでした。GitHubリポジトリもアーカイブされ、READMEの冒頭には保守を終えたことと後継のUniverを使うよう書かれています。この記事では、Luckysheetの機能と現在の配布状況、既存の画面を動かし続けるための導入コードと保存処理、Univerへデータを移す変換コード、Handsontableとの選び分けまでを扱います。Luckysheetで作った画面を抱えている開発者と、Web上の表計算ライブラリを選んでいる担当者に向けた内容です。
まとめ:Luckysheetを新規採用しない理由と既存画面を移す時期の判断基準
新しい案件でLuckysheetを選ぶ理由は、もうありません。5年近く更新が無く、依存しているjQuery 2.2.4には既知のXSS勧告が4件残っています。表示言語に日本語も用意されていないため、利用者向けの画面では文言の差し替えから始めることになります。
既存の画面は、社内ネットワークの中だけで使い、貼り付けや入力値を信頼できる場合に限って当面は残せます。外部の利用者が触る画面、または改修の予定がある画面は、後継のUniverへ移す計画を立ててください。複数シートの表計算が要件ならUniver、Excelと同じ手つきの大量入力が主ならHandsontableが移行先の第一候補です。
Luckysheetの定義とExcel風Web表計算の機能群・2021年で停止した配布状況
Luckysheetのリポジトリは現在GitHubのdream-num組織にあり、npmの公開者名はmengshukejiです。採用を考える前に、何ができて、どこで止まっているかを押さえておきます。
ブラウザだけで動く表計算としての立ち位置とHandsontableとの設計の違い
GitHubのREADMEによると、Luckysheetは純粋なフロントエンドで動く表計算です。書式設定、条件付き書式、セル結合、データ検証、数式と関数、フィルターと並べ替え、ピボットテーブル、グラフ、コメント、共同編集まで1つのライブラリに入っていました。シート見出しやツールバーを含めた「Excelの画面そのもの」を描く点が特徴です。
同じ「Excel風の表」でも、Handsontableは1枚の表をアプリの画面に部品として埋め込む設計です。ツールバーやシート切り替えは持たず、列の型や入力チェックを開発者がコードで決めます。Luckysheetは利用者に表計算ソフトを渡す道具、Handsontableは業務画面の入力欄を表にする道具、と分けて考えると選び分けを誤りません。
npm最終版2.1.13とGitHubアーカイブ化で確定した保守終了の時点
npm registryの記録では、luckysheetパッケージは2020年9月14日に初公開され、最後の版は2021年1月19日の2.1.13です。GitHubリポジトリは読み取り専用のアーカイブ状態で、説明文は「Luckysheet upgraded to Univer」に変わっていました。スター数は2026年11月2日時点で16,630件あり、検索で今も見つかるのはこの蓄積のためです。
公式ドキュメントも残っていますが、各ページの冒頭に「Luckysheet is no longer maintained, please use Univer instead!」と表示されます。Excelファイルの入出力を担うLuckyexcelも同じくアーカイブ済みで、npmの最終版は2021年1月4日の1.0.1です。不具合を見つけても、本家に修正が入ることはありません。
依存するjQuery 2.2.4に残るXSS勧告4件と配布ファイル約3MBの重さ
2.1.13のpackage.jsonは、実行時の依存にjquery ^2.2.4を指定しています。jQuery 2系の最終版は2.2.4なので、npmで入れると必ずこの版になります。脆弱性データベースのOSVで照会すると、jQuery 2.2.4にはGHSA-gxr4-xjj5-5px2(CVE-2020-11022)を含むXSSの勧告が4件登録されていました。Luckysheet本体の勧告は0件でしたが、更新が止まったライブラリは調べる人もいないため、0件を安全の根拠にはできません。
配布ファイルの大きさも見ておきます。jsDelivrから取得したdist/luckysheet.umd.jsは3,050,103バイトで、gzip圧縮しても約621KBでした。同時に読むplugin.jsは約171KBです。Handsontable 18.1.2の本体が圧縮後で約319KBなので、その2倍を超える量を表の画面を開くたびに読み込むことになります。
既存案件でLuckysheetを動かす導入コードとセルデータの保存処理の要点
すでにLuckysheetで動いている画面を保守する場合や、移行前に挙動を確かめたい場合のために、最小の構成と保存処理を示します。新規案件での利用は勧めません。
CDNの版を2.1.13に固定して表を出す最小構成とlang設定の制約
READMEの導入例はCDNから@latestで読み込む形ですが、保守する画面では版を固定し、できれば自社のサーバーに置いて配信してください。外部CDNの障害や配信停止で、画面が開かなくなる事態を避けるためです。
<!-- index.html:Luckysheet 2.1.13 を版固定で読み込む最小構成 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/plugins/css/pluginsCss.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/plugins/plugins.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/luckysheet.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/assets/iconfont/iconfont.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/plugins/js/plugin.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/luckysheet.umd.js"></script>
<div id="luckysheet" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>
<script>
luckysheet.create({
container: 'luckysheet', // 表を描く要素のid
title: '発注明細',
lang: 'en', // 日本語は無い(zh・en・zh_tw・es のみ)
showtoolbar: true,
data: [{
name: '明細', index: 'orders', order: 0, status: 1,
celldata: [
{ r: 0, c: 0, v: { v: '品番', m: '品番', ct: { fa: 'General', t: 'g' } } },
{ r: 0, c: 1, v: { v: '数量', m: '数量', ct: { fa: 'General', t: 'g' } } },
{ r: 1, c: 0, v: { v: 'A-001', m: 'A-001', ct: { fa: 'General', t: 'g' } } },
{ r: 1, c: 1, v: { v: 120, m: '120', ct: { fa: 'General', t: 'n' } } },
],
config: {}, // 空でも {} を渡す(null や空文字は不可)
}],
});
</script>
全体設定のページでは、langが受け付けるのは簡体字中国語・英語・繁体字中国語・スペイン語の4つです。日本語の画面にするには、言語ファイルを自前で書き換えるしかありません。シート設定のページの注意書きどおり、configをnullにすると初期化で失敗します。
celldataとdataの二つの形式とtransToCellDataで保存用に戻す手順
Luckysheetのセルには、2つの持ち方があります。celldataは値の入ったセルだけを{r, c, v}で並べる1次元配列で、初期化と保存に使います。dataは全セルをdata[行][列]で持つ2次元配列で、空のセルはnullです。初期化の時点でcelldataはdataに変換され、以後の編集はdata側に反映されます。
セルの中身はセル属性の表で定義されています。vが元の値、mが表示用の文字列、fが=MAX(A7:A9)のような数式、ctが書式です。背景色はbg、太字はblのように、書式も1セルずつ短い名前で持ちます。
保存するときは、luckysheet.getAllSheets()で全シートを取り出し、transToCellData()でdataをcelldataに戻してから送ります。2次元配列のまま保存すると、1,000行×26列なら空セルのnullだけで2万6,000要素を抱えることになるためです。
cellUpdatedフックで変更セルを受け取りサーバーへ差分を送る実装
ブック全体を毎回送る方式では、2人が同じブックを開いたときに後から保存した人の内容で上書きされます。変更したセルだけを送るなら、hookのcellUpdatedを使います。
// luckysheet.create のオプションに追加する:変更セルだけを集めて送る
const pending = new Map();
hook: {
cellUpdated(r, c, oldValue, newValue) {
const value = newValue && typeof newValue === 'object' ? newValue.v : newValue;
pending.set(`${r}:${c}`, { r, c, value, formula: newValue?.f ?? null });
},
},
// 保存ボタンで1回にまとめて送る
async function flush() {
if (pending.size === 0) return;
const cells = [...pending.values()];
pending.clear();
await fetch('/api/books/orders/cells', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(cells),
});
}
cellUpdatedの引数は行番号・列番号・変更前のセル・変更後のセル・再描画の有無の5つです。行の挿入や削除はcellUpdatedでは届かず、すべての操作を受けるupdatedフックで扱います。行を挿入すると、送信済みの行番号がずれる点に注意してください。行番号ではなく行ごとのIDで更新する設計にしておくと、移行先のライブラリでも同じAPIが使えます。
後継Univerと派生FortuneSheetへ移すときのデータ変換と機能差の確認
移行先の候補は、開発元が後継と位置づけるUniverと、Luckysheetから派生したFortuneSheetの2つです。どちらも、Luckysheetのコードを差し替えるだけでは動きません。
Univer 1.3.1の導入コードと日本語ロケールja-JPを指定する設定
Univerの最新版は、2026年10月30日公開の1.3.1です(npm registryで確認)。公式のInstallationページでは、まとめて機能を読み込むプリセット方式が案内されています。例は英語ですが、@univerjs/preset-sheets-core 1.3.1にはja-JPの言語ファイルが同梱されており、LocaleType.JA_JPを指定すれば日本語の画面になります。
npm install @univerjs/presets @univerjs/preset-sheets-core
// main.js:Univer 1.3 系で日本語の表計算を表示する(index.html に <div id="app" style="height: 600px"></div>)
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core';
import UniverPresetSheetsCoreJaJP from '@univerjs/preset-sheets-core/locales/ja-JP';
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets';
import '@univerjs/preset-sheets-core/lib/index.css';
const { univerAPI } = createUniver({
locale: LocaleType.JA_JP,
locales: {
[LocaleType.JA_JP]: mergeLocales(UniverPresetSheetsCoreJaJP),
},
presets: [UniverSheetsCorePreset({ container: 'app' })],
});
univerAPI.createWorkbook({});
LuckysheetがjQueryとwindow.luckysheetに頼っていたのに対し、Univerはnpmで入れてバンドラで組み込む前提です。CDNの<script>タグを並べていた画面は、ビルドの仕組みから作り直すことになります。
LuckysheetのシートをUniverのIWorkbookDataへ写す変換コード
UniverのブックはIWorkbookDataという形で、シートの並び順sheetOrderと、シートIDをキーにしたsheetsを持ちます。ワークシートの構造では、セルをcellData[行][列]の入れ子のオブジェクトで持ち、結合範囲をmergeDataの配列で持ちます。Luckysheetのcelldataから写す最小の変換は次のとおりです。
// Luckysheet のシート(celldata 形式)を Univer の IWorksheetData に写す
function toUniverSheet(sheet, i) {
const cellData = {};
for (const { r, c, v } of sheet.celldata ?? []) {
if (v == null) continue;
const cell = typeof v === 'object' ? v : { v };
cellData[r] ??= {};
cellData[r][c] = cell.f ? { f: cell.f, v: cell.v } : { v: cell.v ?? cell.m };
}
const mergeData = Object.values(sheet.config?.merge ?? {}).map(({ r, c, rs, cs }) => ({
startRow: r, endRow: r + rs - 1, startColumn: c, endColumn: c + cs - 1,
}));
return {
id: `sheet-${i + 1}`,
name: sheet.name,
rowCount: Math.max(sheet.row ?? 0, 1000),
columnCount: Math.max(sheet.column ?? 0, 26),
cellData,
mergeData,
};
}
const sheets = luckySheets.map(toUniverSheet); // luckySheets は保存済みの getAllSheets() の結果
univerAPI.createWorkbook({
id: 'orders-book',
name: '発注明細',
sheetOrder: sheets.map((s) => s.id),
sheets: Object.fromEntries(sheets.map((s) => [s.id, s])),
});
このコードは値・数式・結合だけを移し、書式は意図して落としています。セルの定義では、書式はsにスタイルIDかスタイルのオブジェクトを入れる形です。Luckysheetのbgやblとは名前も構造も違うため、使っている書式の種類を洗い出し、対応表を作ってから変換に足してください。条件付き書式・データ検証・コメントはUniverでは別のプラグインの設定になるので、対象の機能ごとに移し先を確認します。
オープンソース版Univerに無いExcel入出力・ピボット・グラフの扱い
移行で最も見落としやすいのは、無償で使える範囲の差です。Luckysheetではピボットテーブルとグラフが本体に入り、Excelの読み込みもLuckyexcelで無償でした。Univerの料金ページでは、Apache-2.0のオープンソース版はOfficeファイルの変換・リアルタイム共同編集・ピボットテーブル・グラフに対応していません。これらは商用ライセンスの機能で、Businessプランは月99ドルからです。入出力のページによると、.xlsxの変換には変換用のバックエンドも必要になります。
Luckysheetで.xlsxの取り込みを使っていた画面は、移行の見積もりにこの差を必ず入れてください。費用を出さない場合は、SheetJSでファイルを読んでセルの値を取り出し、上の変換コードと同じ要領でcellDataに詰める方法があります。書式付きの帳票を出力するだけなら、表計算の画面とは切り離してExcelJSでサーバー側から生成するほうが、Univerの有償機能に頼らずに済みます。
Luckysheet互換のデータ構造を保つFortuneSheetを選ぶ条件と注意点
FortuneSheetは、READMEで「Luckysheetから生まれた」と明記しているMITライセンスの派生プロジェクトです。データ構造の大部分がLuckysheetと互換で、主な違いはシートのindexがidに変わった点だと説明されています。npmの最新は2025年11月6日公開の@fortune-sheet/react 1.0.4で、Reactの部品として組み込みます。
FortuneSheetを選んでよいのは、画面がReactで、保存済みのLuckysheetのデータを大きく変換せずに移したい場合です。Vue対応はロードマップにあるものの未完了で、.xlsxの入出力も本体ではなく別プロジェクトのプラグインです。GitHubのスター数は3,746件とUniverの22,845件を大きく下回り、開発体制の厚みでは劣ります。長く使う画面の移行先としてはUniverを先に検討し、FortuneSheetは変換工数を最小にしたい短期案件に限るのが妥当です。
LuckysheetとHandsontable・Univerの案件条件に応じた選定基準
ここまでの事実をもとに、既存画面の扱いと新規案件の選び方を条件で切り分けます。
既存のLuckysheet画面を当面残してよい条件と移行の期限を切る基準
次の3つがそろう画面は、すぐに作り直さなくても構いません。社内ネットワークからしか開けないこと、入力するのが社員に限られること、表計算の機能を追加する予定が無いことです。この場合も、版を2.1.13に固定し、配布ファイルを自社のサーバーに置いてください。
逆に、取引先や一般の利用者が開く画面、他システムから取り込んだ文字列をそのまま表示する画面は、移行を先送りしないでください。jQuery 2.2.4のXSS勧告は、外から来たHTMLを扱う箇所で問題になる種類のものです。機能追加の依頼が来た時点も、移行の区切りとして判断してください。止まったライブラリに手を入れる工数は、移行の工数に上乗せされるだけだからです。
新規案件をUniver・Handsontable・データグリッドへ振り分ける比較
新しく表の画面を作るときは、利用者が「表計算ソフト」を使うのか「入力欄が表になった画面」を使うのかで分けます。
| ライブラリ(2026年11月2日時点の版) | ライセンス | 向く場面 |
|---|---|---|
| Luckysheet 2.1.13 | MIT(保守終了) | 新規採用しない |
| Univer 1.3.1 | Apache-2.0(一部機能は有償) | 複数シートの表計算 |
| FortuneSheet 1.0.4 | MIT | Luckysheetデータの短期移行 |
| Handsontable 18.1.2 | 独自(商用は有償) | Excel同等の大量入力 |
| AG Grid Community | MIT(上位版は有償) | 閲覧中心の一覧と軽い編集 |
実務では、利用者がシートを足したり自由に数式を書いたりするならUniver、列の構成が決まった明細を速く直すならHandsontableです。閲覧が主で編集が少ない一覧なら、AG Gridのような表示寄りのデータグリッドで足ります。ライセンスの違いを確かめるときは、オープンソースライセンスの商用利用可否を前提知識として押さえておくと判断が速くなります。
表計算の画面をWeb化する前に決める保存単位と権限の設計範囲
どのライブラリを選んでも、表の部品が決めてくれないことがあります。ブック全体を1つのデータとして保存するのか、セルや行の単位で保存するのか。誰がどのシートやどの列を直せるのか。2人が同時に開いたときに、どちらの変更を残すのか。Luckysheetの画面で起きていた上書き事故の多くは、この3点を決めないまま表計算の画面を置いたことが原因です。
ブック単位の保存はExcelファイルを共有フォルダに置く運用と変わらず、Web化しても事故の起き方は同じになります。Excelのままで回せる範囲の条件は、エクセル管理の限界はどこかで整理しました。表の操作感と、裏側の保存単位・権限・変更履歴を一体で設計する場合は、業務用・Webアプリ開発として、既存のLuckysheet画面の移行も含めて要件の段階から相談いただけます。
よくある質問:Luckysheetの日本語化・Excel読み込み・商用利用・後継
Luckysheetについてよく出る質問に、2026年11月2日時点の公式情報をもとに答えます。
Luckysheetは今もダウンロードして使えますか?
使えます。npmの2.1.13とGitHubのソースは公開されたままで、CDNからも読み込めます。ただし2021年1月以降は更新が無く、リポジトリもアーカイブされているため、不具合や脆弱性が見つかっても修正は出ません。既存画面の保守に限って使い、新規の案件では後継のUniverなどを選んでください。
Luckysheetの画面を日本語にできますか?
標準ではできません。langで選べるのは簡体字中国語・英語・繁体字中国語・スペイン語の4つで、日本語の言語ファイルは用意されていません。日本語にするには、言語ファイルを複製して文言を自前で訳し、ビルドし直す必要があります。後継のUniver 1.3.1は日本語の言語ファイルを同梱しており、LocaleType.JA_JPを指定するだけで日本語の画面になります。
LuckysheetでExcelファイルを読み込むにはどうしますか?
Luckysheetでは、同じ開発元のLuckyexcelで.xlsxをLuckysheetの形式に変換して読み込んでいました。Luckyexcelもnpmの最終版は2021年1月の1.0.1で、リポジトリはアーカイブ済みです。移行するなら、Univerの商用機能の変換を使うか、SheetJSでセルの値を読み取ってUniverのcellDataに詰める方法を選びます。後者は書式が移らない点を見積もりに入れてください。
Luckysheetは商用の業務システムで使ってもよいですか?
GitHubのリポジトリはMITライセンスなので、商用利用そのものは認められています。ライセンス表示を残せば、社内の業務システムに組み込んでも費用はかかりません。問題はライセンスではなく保守です。依存するjQuery 2.2.4に既知のXSS勧告が残っているため、外部の利用者が触る画面に使うと、脆弱性診断で指摘を受ける可能性が高くなります。
Luckysheetの後継はUniverとFortuneSheetのどちらですか?
開発元が公式に後継と位置づけているのはUniverです。GitHubの説明文も「Luckysheet upgraded to Univer」に変わっています。ただしデータ構造とAPIは作り直されているため、移行には変換が必要です。FortuneSheetは第三者による派生で、Luckysheetとデータ構造の大部分が互換です。長く使う画面ならUniver、Reactの画面で変換を最小にしたい短期案件ならFortuneSheetが候補になります。
関連記事
- Handsontableとは:18系の導入コードと保存処理・商用ライセンスで迷わない採用判断:Excel同等の大量入力画面へ移すときの移行先です
- SheetJSとは:ブラウザとNode.jsでExcelを読み書きする使い方、無償版の範囲とnpm版の脆弱性:Luckyexcelの代わりに.xlsxを読み込む方法を確認できます
- ExcelJSとは:Node.jsでExcel帳票を作る使い方と10万行の出力、保守停止の注意点:表計算の画面と切り離して帳票を出力するときに役立ちます
- 業務アプリとは?業務システムとの違い・作り方3通りと内製と外注の判断基準:表計算を組み込む業務アプリ全体の作り方を選ぶ前提です
- オープンソースライセンスとは?主要9種の商用利用可否と義務を条項番号で解説:MIT・Apache-2.0・独自ライセンスの違いを確認できます