Importer Web SDK via un CDN

Exécutez d’abord l’exemple complet, puis copiez-le dans votre page. Il inclut les dépendances, styles, langues et enregistrements Facade nécessaires à une feuille modifiable avec calcul des formules.

Essayer une feuille modifiable

  1. Ouvrez l’exemple, ou téléchargez le HTML ci-dessous sous le nom index.html.
  2. Ouvrez-le dans un navigateur moderne connecté à Internet. Aucun outil de compilation ni serveur n’est nécessaire. L’interface et les données de l’exemple sont en français.
  3. Le total du cahier est 36. Passez la quantité de 3 à 4 : le total devient 48. Vous pouvez aussi modifier les cellules et annuler vos changements.
Télécharger le HTML

Exemple HTML complet

Cet exemple utilise React 18.3.1 UMD. Son objet global React n’expose pas jsx et jsxs, attendus par les bundles UMD Univer. Les deux lignes ci-dessous fournissent ces entrées via l’API publique React.createElement. Avec un gestionnaire de paquets, l’outil de compilation résout react/jsx-runtime : ne recopiez pas ce pont UMD dans cette configuration.

Les ressources sont chargées dans l’ordre des dépendances depuis jsDelivr. En cas d’échec, l’exemple réessaie la même version sur unpkg avant de continuer. Si les deux fournisseurs échouent, le démarrage s’arrête et la ressource manquante s’affiche sur la page.

HTML
<!doctype html><html lang="fr-FR">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Exemple CDN Univer Sheets</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">Chargement de 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/fr-FR.js',        '@univerjs/ui@1.4.0/lib/umd/locale/fr-FR.js',        '@univerjs/sheets@1.4.0/lib/umd/locale/fr-FR.js',        '@univerjs/sheets-ui@1.4.0/lib/umd/locale/fr-FR.js',        '@univerjs/docs-ui@1.4.0/lib/umd/locale/fr-FR.js',        '@univerjs/sheets-formula-ui@1.4.0/lib/umd/locale/fr-FR.js',        '@univerjs/sheets-numfmt-ui@1.4.0/lib/umd/locale/fr-FR.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.FR_FR,          locales: {            [LocaleType.FR_FR]: mergeLocales(              UniverDesignFrFR,              UniverUiFrFR,              UniverSheetsFrFR,              UniverSheetsUiFrFR,              UniverDocsUiFrFR,              UniverSheetsFormulaUiFrFR,              UniverSheetsNumfmtUiFrFR,            ),          },        })        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([            ['Article', 'Quantité', 'Prix', 'Total'],            ['Cahier', 3, 12, '=B2*C2'],            ['Stylo', 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 =          'Le chargement de l’exemple a échoué. Vérifiez la connexion puis actualisez la page.' + '\n' + error.message      })    </script>  </body></html>

Conventions de nommage

Les scripts UMD exposent les exports des modules dans des objets globaux. Utilisez ces noms pour accéder aux plugins et aux API Facade lors de l’initialisation :

Paquet ou point d’entréeNom global
@univerjs/coreUniverCore
@univerjs/docs-uiUniverDocsUi
@univerjs/core/facadeUniverCoreFacade
@univerjs/docs-ui/locale/fr-FRUniverDocsUiFrFR

Aligner les versions

Cet exemple fixe Univer à 1.4.0, React et ReactDOM à 18.3.1, et RxJS à 7.8.2. Lors d’une mise à niveau, changez toutes les URL Univer ensemble, y compris Facade, CSS et langues. Évitez de charger une seconde copie de ces bibliothèques à côté du bundle de votre application.

Dépannage

SymptômeÀ vérifier
ITelemetryServiceChargez @univerjs/telemetry avant @univerjs/sheets-ui, qui en dépend. Conservez la liste complète des dépendances.
FDocumentChargez @univerjs/docs/facade avant @univerjs/docs-ui/facade ; Sheets utilise aussi le moteur de texte Docs.
[redi], t is not a functionRepartez de l’exemple complet, avec une seule copie de chaque dépendance et des versions cohérentes. Vérifiez les requêtes échouées dans Network.
Éditeur videDonnez une hauteur au conteneur. Si le réseau ou la CSP bloque le CDN, hébergez les dépendances vous-même ou utilisez un gestionnaire de paquets.

Pour une application React ou Vue existante, privilégiez l’installation par gestionnaire de paquets, qui gère les dépendances et évite une longue liste de scripts à maintenir.

Que pensez-vous de ce guide ?

© 2026 DreamNum Co., Ltd.