CDN 経由での Web SDK のインポート
まず完全なサンプルを実行してから、自分のページにコピーしてください。編集可能なシートと数式計算に必要な依存関係、CSS、言語パック、Facade 登録を含みます。
編集できるシートを試す
- サンプルを開くか、下の HTML をダウンロードして
index.htmlとして保存します。 - インターネットに接続した最新のブラウザーで開きます。ビルドツールやサーバーは不要です。サンプルの UI と表の内容は日本語です。
- ノートの合計は 36 です。数量を 3 から 4 にすると 48 になります。セルの編集や元に戻す操作も試せます。
完全な HTML サンプル
この例では React 18.3.1 UMD を使います。グローバル React オブジェクトには Univer の UMD バンドルが必要とする jsx と jsxs がないため、以下の2行で公開 API の React.createElement に接続します。パッケージマネージャーを使う場合はビルドツールが react/jsx-runtime を解決するため、この UMD 用の処理は不要です。
依存順に jsDelivr からリソースを読み込みます。リクエストが失敗した場合は、unpkg から同じバージョンを再試行してから続行します。両方で失敗した場合は起動を停止し、読み込めなかったリソースを表示します。
HTML
<!doctype html><html lang="ja-JP"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Univer Sheets CDN サンプル</title> <style> html, body, #root, #app { padding: 0; margin: 0; height: 100%; } </style> </head> <body> <div id="app"><p role="status" style="padding: 24px; font-family: system-ui">Univer を読み込み中…</p></div> <script> const cdnBases = ['https://cdn.jsdelivr.net/npm/', 'https://unpkg.com/'] const app = document.getElementById('app') async function loadResource(path, tag = 'script') { for (const base of cdnBases) { const element = document.createElement(tag) const url = base + path element.crossOrigin = 'anonymous' if (tag === 'link') { element.rel = 'stylesheet' element.href = url } else { element.src = url } try { await new Promise((resolve, reject) => { element.onload = () => resolve() element.onerror = () => reject(new Error(url)) document.head.appendChild(element) }) return } catch { element.remove() } } throw new Error(`Could not load ${path} from ${cdnBases.join(' or ')}`) } const styles = [ '@univerjs/design@1.4.0/lib/index.css', '@univerjs/ui@1.4.0/lib/index.css', '@univerjs/docs-ui@1.4.0/lib/index.css', '@univerjs/sheets-ui@1.4.0/lib/index.css', '@univerjs/sheets-formula-ui@1.4.0/lib/index.css', '@univerjs/sheets-numfmt-ui@1.4.0/lib/index.css', ] const reactScripts = [ 'react@18.3.1/umd/react.production.min.js', 'react-dom@18.3.1/umd/react-dom.production.min.js', ] const sdkScripts = [ 'rxjs@7.8.2/dist/bundles/rxjs.umd.min.js', '@wendellhu/redi@1.1.3/dist/umd/index.js', '@wendellhu/redi@1.1.3/dist/umd/react-bindings/index.js', '@univerjs/themes@1.4.0/lib/umd/index.js', '@univerjs/protocol@1.4.0/lib/umd/index.js', '@univerjs/core@1.4.0/lib/umd/index.js', '@univerjs/network@1.4.0/lib/umd/index.js', '@univerjs/rpc@1.4.0/lib/umd/index.js', '@univerjs/design@1.4.0/lib/umd/index.js', '@univerjs/engine-render@1.4.0/lib/umd/index.js', '@univerjs/engine-formula@1.4.0/lib/umd/index.js', '@univerjs/drawing@1.4.0/lib/umd/index.js', '@univerjs/telemetry@1.4.0/lib/umd/index.js', '@univerjs/ui@1.4.0/lib/umd/index.js', '@univerjs/docs@1.4.0/lib/umd/index.js', '@univerjs/docs-ui@1.4.0/lib/umd/index.js', '@univerjs/sheets@1.4.0/lib/umd/index.js', '@univerjs/sheets-ui@1.4.0/lib/umd/index.js', '@univerjs/sheets-formula@1.4.0/lib/umd/index.js', '@univerjs/sheets-formula-ui@1.4.0/lib/umd/index.js', '@univerjs/sheets-numfmt@1.4.0/lib/umd/index.js', '@univerjs/sheets-numfmt-ui@1.4.0/lib/umd/index.js', '@univerjs/core@1.4.0/lib/umd/facade.js', '@univerjs/engine-formula@1.4.0/lib/umd/facade.js', '@univerjs/ui@1.4.0/lib/umd/facade.js', '@univerjs/docs@1.4.0/lib/umd/facade.js', '@univerjs/docs-ui@1.4.0/lib/umd/facade.js', '@univerjs/sheets@1.4.0/lib/umd/facade.js', '@univerjs/sheets-ui@1.4.0/lib/umd/facade.js', '@univerjs/sheets-formula@1.4.0/lib/umd/facade.js', '@univerjs/sheets-numfmt@1.4.0/lib/umd/facade.js', '@univerjs/design@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/ui@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/sheets@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/sheets-ui@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/docs-ui@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/sheets-formula-ui@1.4.0/lib/umd/locale/ja-JP.js', '@univerjs/sheets-numfmt-ui@1.4.0/lib/umd/locale/ja-JP.js', ] // Fetch ahead in parallel; main() still executes scripts in dependency order. for (const [as, paths] of [ ['style', styles], ['script', [...reactScripts, ...sdkScripts]], ]) { for (const path of paths) { const preload = document.createElement('link') preload.rel = 'preload' preload.as = as preload.crossOrigin = 'anonymous' preload.href = cdnBases[0] + path preload.onerror = () => { preload.onerror = null preload.href = cdnBases[1] + path } document.head.appendChild(preload) } } async function main() { for (const path of styles) await loadResource(path, 'link') for (const path of reactScripts) await loadResource(path) // Bridge the React 18 UMD global to the JSX runtime expected by Univer UMD bundles. React.jsx = (type, props, key) => React.createElement(type, key === undefined ? props : { ...props, key }) React.jsxs = React.jsx for (const path of sdkScripts) await loadResource(path) app.textContent = '' const { Univer, LocaleType, mergeLocales, UniverInstanceType } = UniverCore const { FUniver } = UniverCoreFacade const { UniverRenderEnginePlugin } = UniverEngineRender const { UniverFormulaEnginePlugin } = UniverEngineFormula const { UniverUIPlugin } = UniverUi const { UniverSheetsPlugin } = UniverSheets const { UniverSheetsUIPlugin } = UniverSheetsUi const { UniverDocsPlugin } = UniverDocs const { UniverDocsUIPlugin } = UniverDocsUi const { UniverSheetsFormulaPlugin } = UniverSheetsFormula const { UniverSheetsFormulaUIPlugin } = UniverSheetsFormulaUi const { UniverSheetsNumfmtPlugin } = UniverSheetsNumfmt const { UniverSheetsNumfmtUIPlugin } = UniverSheetsNumfmtUi const univer = new Univer({ locale: LocaleType.JA_JP, locales: { [LocaleType.JA_JP]: mergeLocales( UniverDesignJaJP, UniverUiJaJP, UniverSheetsJaJP, UniverSheetsUiJaJP, UniverDocsUiJaJP, UniverSheetsFormulaUiJaJP, UniverSheetsNumfmtUiJaJP, ), }, }) univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverFormulaEnginePlugin) univer.registerPlugin(UniverUIPlugin, { container: 'app', }) univer.registerPlugin(UniverDocsPlugin) univer.registerPlugin(UniverDocsUIPlugin) univer.registerPlugin(UniverSheetsPlugin) univer.registerPlugin(UniverSheetsUIPlugin) univer.registerPlugin(UniverSheetsFormulaPlugin) univer.registerPlugin(UniverSheetsFormulaUIPlugin) univer.registerPlugin(UniverSheetsNumfmtPlugin) univer.registerPlugin(UniverSheetsNumfmtUIPlugin) univer.createUnit(UniverInstanceType.UNIVER_SHEET, {}) const univerAPI = FUniver.newAPI(univer) window.univerAPI = univerAPI univerAPI .getActiveWorkbook() .getActiveSheet() .getRange('A1:D3') .setValues([ ['商品', '数量', '単価', '合計'], ['ノート', 3, 12, '=B2*C2'], ['ペン', 5, 2, '=B3*C3'], ]) } main().catch((error) => { console.error(error) app.setAttribute('role', 'alert') app.style.cssText = 'padding: 24px; box-sizing: border-box; white-space: pre-wrap; overflow-wrap: anywhere; font: 14px/1.5 system-ui' app.textContent = 'サンプルの読み込みに失敗しました。接続を確認してページを更新してください。' + '\n' + error.message }) </script> </body></html>名前空間の規則
UMD スクリプトはモジュールのエクスポートをグローバルオブジェクトとして公開します。初期化コードでは、以下の名前でプラグインや Facade API にアクセスします。
| パッケージまたはエントリー | グローバル名 |
|---|---|
@univerjs/core | UniverCore |
@univerjs/docs-ui | UniverDocsUi |
@univerjs/core/facade | UniverCoreFacade |
@univerjs/docs-ui/locale/ja-JP | UniverDocsUiJaJP |
バージョンをそろえる
このサンプルは Univer 1.4.0、React と ReactDOM 18.3.1、RxJS 7.8.2 に固定しています。更新時は Facade、CSS、言語ファイルを含むすべての Univer URL を同時に変更してください。既存アプリのバンドルと同じライブラリを二重に読み込まないでください。
トラブルシューティング
| 症状 | 確認すること |
|---|---|
ITelemetryService | @univerjs/telemetry に依存する @univerjs/sheets-ui より先に読み込み、完全な依存一覧を維持してください。 |
FDocument | @univerjs/docs-ui/facade より先に @univerjs/docs/facade を読み込みます。Sheets も Docs のテキストエンジンを使用します。 |
[redi], t is not a function | 完全なサンプルから始め、各依存を同じバージョンで一度だけ読み込みます。ブラウザーの Network で失敗したリクエストを確認してください。 |
| エディターが空白 | コンテナーに高さを指定します。ネットワークや CSP が CDN を遮断する場合は、自分で配信する依存かパッケージマネージャーを使用してください。 |
既存の React や Vue アプリでは、依存関係を管理できるパッケージマネージャーによる導入を推奨します。長いスクリプト一覧を保守する必要がありません。
このガイドはいかがですか?