Skip to Content
🎉 Univer 0.6.1 版本已发布。查看详情 →
GuidesUniver Sheets开始使用安装和基本使用

安装和基本使用

Univer 有着插件化的设计,我们提供了丰富的插件,以便让你更加灵活地构建出属于自己的电子文档应用。你可以根据自身需求选择性地手动组合引入并使用这些插件。

从 0.5.0 版本起 Univer 提供了 @univerjs/presets 包,可以帮助你快速地搭建一个 Univer 应用而无需关心插件化的设计以及如何引入和配置注册那些繁杂的插件。因此,如果你是首次使用 Univer 的开发者,我们推荐你从 Presets 开始。

⚠️

需要注意的是,无论是使用 Presets 包还是手动组合安装的方式,你都必须保证所有的 preset 或插件版本号一致

本章将带你了解如何使用 Univer 的 Presets 包或者通过手动组合安装插件的方式来构建一个最基本的 Univer Sheets 应用。

使用 Presets

Univer Presets 基于电子文档的功能场景,提供了一系列的插件组合,以便让你快速地搭建一个 Univer 应用。一个 preset 中通常包含包含了插件、样式文件、语言包、Facade API。

在这里我们将简单介绍下如何通过不到二十行的代码来快速搭建一个 Univer Sheets 应用。

使用包管理器

如果你的项目中已经引入了现代前端开发工具,那么引入 Univer 将会非常简单。我们推荐使用 ViteesbuildWebpack 5 等对 ES Module 支持较好的构建工具来构建 Univer 应用。如果你使用了其它构建工具(例如 Webpack 4),可能会需要一些额外的配置,请阅读 常见问题 获取更多信息。

安装

选择你所使用的包管理器以安装 @unvierjs/presets

npm install @univerjs/presets

使用

通过以下代码,你就可以启动一个 Univer Sheets 应用:

⚠️

如果你的构建工具不支持 package.json 的 exports 字段(常见于 Webpack 4),你需要手动将映射的路径修改为实际的路径。

import { createUniver, defaultTheme, LocaleType, merge } from '@univerjs/presets'; import { UniverSheetsCorePreset } from '@univerjs/presets/preset-sheets-core'; import UniverPresetSheetsCoreZhCN from '@univerjs/presets/preset-sheets-core/locales/zh-CN'; import '@univerjs/presets/lib/styles/preset-sheets-core.css'; const { univer, univerAPI } = createUniver({ locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: merge( {}, UniverPresetSheetsCoreZhCN, ), }, theme: defaultTheme, presets: [ UniverSheetsCorePreset({ container: 'app', }), ], }); univerAPI.createWorkbook({ name: 'Test Sheet' });
createUniver 方法

createUniver 方法接受一个配置对象,其中包含了 Univer 的配置信息,例如语言、主题、插件等。这个方法会返回一个包含了 Univer 实例和 Univer Facade API 实例的对象。

配置对象的属性如下:

  • locale:语言环境,可以是 LocaleType 枚举值。
  • locales:语言包,一个对象,键为语言环境,值为语言包对象。
  • theme:主题,一个主题对象。
  • presets:一个 preset 数组,包含了需要注册的预设包,例如 UniverSheetsCorePreset
  • plugins:一个插件数组,包含了需要额外注册的插件。

当你使用了一个未包含在任何预设包中的插件或者你自己实现了一个插件时,可以通过 plugins 属性来注册这些插件。也可以选择在获得 Univer 实例后通过 univer.registerPlugin 方法来注册插件。

通过 <script> 标签引入

如果你不使用包管理工具,你也可以通过 <script> 标签引入 Univer。

我们在当前主流的 CDN 服务商(例如 jsDelivr、unpkg)都提供了 Univer 的 UMD 构建,你可以在 HTML 文件中引入这些资源(当然你也可以下载这些文件然后通过自己的服务器或者 CDN 网络分发):

示例

<head> <script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/rxjs/dist/bundles/rxjs.umd.min.js"></script> <script src="https://unpkg.com/@univerjs/presets/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/preset-sheets-core/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/preset-sheets-core/lib/umd/locales/zh-CN.js"></script> <link rel="stylesheet" href="https://unpkg.com/@univerjs/preset-sheets-core/lib/index.css" /> <style> html, body, #root, #app { padding: 0; margin: 0; height: 100%; } </style> </head> <body> <div id="app"></div> <script> const { createUniver } = UniverPresets; const { LocaleType, merge } = UniverCore; const { defaultTheme } = UniverDesign; const { UniverSheetsCorePreset } = UniverPresetSheetsCore const { univerAPI } = createUniver({ locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: merge( {}, UniverPresetSheetsCoreZhCN, ), }, theme: defaultTheme, presets: [ UniverSheetsCorePreset(), ], }); univerAPI.createWorkbook({ name: 'Test Sheet' }); // 创建一个名为 'Test Sheet' 的工作表 </script> </body>

这里返回的 univerAPI 对象被称为 Univer 的面板 API(Facade API),通过它可以调用 Univer 提供的许多功能。

指定版本

unpkg 和 jsDeliver 都支持指定特定版本的资源。以 unpkg 为例,如果你想使用 0.5.0 版本的 Univer,仅需在 URL 中加上 @<version> 来指定版本即可:

- https://unpkg.com/@univerjs/presets/lib/umd/index.js + https://unpkg.com/@univerjs/presets@0.5.0/lib/umd/index.js

手动组合安装插件

当你需要更加灵活地控制插件的加载时机,或者想要更加细粒度地按需引入插件时,你可以选择手动组合安装插件。这里仅以最基础的 Univer Sheets 应用为例,介绍如何通过手动组合的方式安装插件。

与 Presets 不同,手动组合安装插件默认并不包含 Facade API,以下代码示例中有关 Facade API 的部分都是可选的,你可以根据自己的需求来决定是否删除。

使用包管理器

安装

Univer 使用了 React 开发视图(当然这并不影响你在 Vue 或者 Angular 中使用 Univer),使用 Rxjs 来处理数据流,由于这两个库被广泛使用在现代前端开发中,因此我们将它们作为 peerDependencies。而不同的包管理工具在对于 peerDependencies 有着不同的行为策略,因此你可能需要注意一些细节。

💡
  • 如果你正在使用 npm,请确保使用的版本为 npm@7 及以上。这是因为 npm@3 ~ npm@6 并不会正确地安装 peerDependencies1
  • 如果你正在使用 pnpm,请确保使用的版本为 pnpm@8 及以上。如果你正在使用 pnpm@6 ~ pnpm@7,可以尝试配置 auto-install-peers=true 2来解决依赖安装问题。
  • 如果你正在使用 yarn,你需要手动安装缺失的 peerDependencies3,不过别担心,下面的安装命令中已经包含了这些依赖。
npm install @univerjs/core @univerjs/design @univerjs/docs @univerjs/docs-ui @univerjs/engine-formula @univerjs/engine-render @univerjs/sheets @univerjs/sheets-formula @univerjs/sheets-formula-ui @univerjs/sheets-numfmt @univerjs/sheets-numfmt-ui @univerjs/sheets-ui @univerjs/ui

使用

💡

样式文件的引入顺序很重要,确保你在依次引入 @univerjs/design@univerjs/ui 的 CSS 样式后再引入其他插件的样式文件。

你需要在项目中引入 Univer 的样式文件、语言包,以及一些必要的插件:

import { LocaleType, merge, Univer, UniverInstanceType } from "@univerjs/core"; import { FUniver } from "@univerjs/core/facade"; import { defaultTheme } from "@univerjs/design"; import { UniverFormulaEnginePlugin } from "@univerjs/engine-formula"; import { UniverRenderEnginePlugin } from "@univerjs/engine-render"; import { UniverUIPlugin } from "@univerjs/ui"; import { UniverDocsPlugin } from "@univerjs/docs"; import { UniverDocsUIPlugin } from "@univerjs/docs-ui"; import { UniverSheetsPlugin } from "@univerjs/sheets"; import { UniverSheetsUIPlugin } from "@univerjs/sheets-ui"; import { UniverSheetsFormulaPlugin } from "@univerjs/sheets-formula"; import { UniverSheetsFormulaUIPlugin } from "@univerjs/sheets-formula-ui"; import { UniverSheetsNumfmtPlugin } from "@univerjs/sheets-numfmt"; import { UniverSheetsNumfmtUIPlugin } from "@univerjs/sheets-numfmt-ui"; import DesignZhCN from '@univerjs/design/locale/zh-CN'; import UIZhCN from '@univerjs/ui/locale/zh-CN'; import DocsUIZhCN from '@univerjs/docs-ui/locale/zh-CN'; import SheetsZhCN from '@univerjs/sheets/locale/zh-CN'; import SheetsUIZhCN from '@univerjs/sheets-ui/locale/zh-CN'; import SheetsFormulaUIZhCN from '@univerjs/sheets-formula-ui/locale/zh-CN'; import SheetsNumfmtUIZhCN from '@univerjs/sheets-numfmt-ui/locale/zh-CN'; // 这里的 Facade API 是可选的,你可以根据自己的需求来决定是否引入 import '@univerjs/engine-formula/facade'; import '@univerjs/ui/facade'; import '@univerjs/docs-ui/facade'; import '@univerjs/sheets/facade'; import '@univerjs/sheets-ui/facade'; import '@univerjs/sheets-formula/facade'; import '@univerjs/sheets-numfmt/facade'; import "@univerjs/design/lib/index.css"; import "@univerjs/ui/lib/index.css"; import "@univerjs/docs-ui/lib/index.css"; import "@univerjs/sheets-ui/lib/index.css"; import "@univerjs/sheets-formula-ui/lib/index.css"; import "@univerjs/sheets-numfmt-ui/lib/index.css";

然后创建一个 Univer 实例,并注册这些插件:

const univer = new Univer({ theme: defaultTheme, locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: merge( {}, DesignZhCN, UIZhCN, DocsUIZhCN, SheetsZhCN, SheetsUIZhCN, SheetsFormulaUIZhCN, SheetsNumfmtUIZhCN ), }, }); 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);

懒加载部分插件

使用手动组合安装方式的一个优势是你可以更加灵活地控制插件的加载时机,一种常见的方式是在应用初始化时仅加载必须的插件,而将部分插件的加载时机延迟到首次渲染完成之后。

Univer 的 官方 demo 就使用了这样的优化技巧,可供参考。

通过 <script> 标签引入

和 Presets 一样 Univer 也为每个插件都提供了 UMD 包,但与之不同的是,你需要手动引入每个插件的 UMD 包。这个过程非常繁琐,我们并不推荐这种方式。请在完全理解插件机制(如插件之间的依赖关系,以及插件样式文件的引入顺序)之后再考虑使用。

示例

我们在当前主流的 CDN 服务商(例如 jsDelivr、unpkg)都提供了 Univer 的 UMD 构建,你可以在 HTML 文件中引入这些资源(当然你也可以下载这些文件然后通过自己的服务器或者 CDN 网络分发):

<head> <script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/rxjs@7.8.1/dist/bundles/rxjs.umd.min.js"></script> <script src="https://unpkg.com/@wendellhu/redi/dist/redi.js"></script> <script src="https://unpkg.com/@wendellhu/redi/dist/react-bindings.js"></script> <script> /** * Starting from Univer 0.6.0, with the support for React 19[^1], UMD users may need additional adaptation. * * [^1]: [support for React 19] https://github.com/dream-num/univer/pull/4247 */ /** * Fix `Uncaught TypeError: client.createRoot is not a function` * If using UMD React < 18, you might need the following code. */ (function (global) { 'use strict'; if (!global.ReactDOM) { throw new Error('ReactDOM must be loaded before ReactCreateRoot.'); } const ReactDOM = global.ReactDOM; if (!ReactDOM.createRoot) { ReactDOM.createRoot = function (container) { return { render: (element) => { ReactDOM.render(element, container); }, }; }; } })(this); /** * Fix `Uncaught TypeError: jsxRuntime.jsx is not a function` * If using UMD React, you might need the following code. * Reference: https://unpkg.com/react@18.3.1/cjs/react-jsx-runtime.production.min.js */ (function (global) { 'use strict'; if (!global.React) { throw new Error('React must be loaded before ReactJSXRuntime.'); } const React = global.React; if (!React.jsx || !React.jsxs) { const REACT_ELEMENT_TYPE = Symbol.for('react.element'); const hasOwnProperty = Object.prototype.hasOwnProperty; const RESERVED_PROPS = { key: true, ref: true, __self: true, __source: true, }; const ReactCurrentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner; function createReactElement(type, config, maybeKey) { const props = {}; let key = null; let ref = null; if (maybeKey !== undefined) { key = `${maybeKey}`; } if (config.key !== undefined) { key = `${config.key}`; } if (config.ref !== undefined) { ref = config.ref; } for (var propName in config) { if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } if (type && type.defaultProps) { const defaultProps = type.defaultProps; for (var propName in defaultProps) { if (props[propName] === undefined) { props[propName] = defaultProps[propName]; } } } return { $$typeof: REACT_ELEMENT_TYPE, type, key, ref, props, _owner: ReactCurrentOwner.current, }; } React.jsx = createReactElement; React.jsxs = createReactElement; } })(this); </script> <script src="https://unpkg.com/@univerjs/protocol/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/core/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/telemetry/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/rpc/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/design/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/engine-render/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/engine-numfmt/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/engine-formula/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/drawing/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/core/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/ui/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/docs/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets-ui/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets-formula/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets-formula-ui/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets-numfmt/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/sheets-numfmt-ui/lib/umd/index.js"></script> <script src="https://unpkg.com/@univerjs/engine-formula/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/ui/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/sheets/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/sheets-ui/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/sheets-formula/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/sheets-numfmt/lib/umd/facade.js"></script> <script src="https://unpkg.com/@univerjs/design/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/ui/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/sheets/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/sheets-ui/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/docs-ui/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/sheets-formula-ui/lib/umd/locale/zh-CN.js"></script> <script src="https://unpkg.com/@univerjs/sheets-numfmt-ui/lib/umd/locale/zh-CN.js"></script> <link rel="stylesheet" href="https://unpkg.com/@univerjs/design/lib/index.css" /> <link rel="stylesheet" href="https://unpkg.com/@univerjs/ui/lib/index.css" /> <link rel="stylesheet" href="https://unpkg.com/@univerjs/docs-ui/lib/index.css" /> <link rel="stylesheet" href="https://unpkg.com/@univerjs/sheets-ui/lib/index.css" /> <link rel="stylesheet" href="https://unpkg.com/@univerjs/sheets-formula-ui/lib/index.css" /> <link rel="stylesheet" href="https://unpkg.com/@univerjs/sheets-numfmt-ui/lib/index.css" /> <style> html, body, #root, #app { padding: 0; margin: 0; height: 100%; } </style> </head> <body> <div id="app"></div> <script> const { Univer, LocaleType, merge, UniverInstanceType } = UniverCore const { FUniver } = UniverCoreFacade const { defaultTheme } = UniverDesign 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({ theme: defaultTheme, locale: LocaleType.ZH_CN, locales: { [LocaleType.ZH_CN]: merge( {}, UniverDesignZhCN, UniverUiZhCN, UniverSheetsZhCN, UniverSheetsUiZhCN, UniverDocsUiZhCN, UniverSheetsFormulaUiZhCN, UniverSheetsNumfmtUiZhCN ), }, }); univer.registerPlugin(UniverRenderEnginePlugin); univer.registerPlugin(UniverFormulaEnginePlugin); univer.registerPlugin(UniverUIPlugin, { container: 'app', }); univer.registerPlugin(UniverSheetsPlugin); univer.registerPlugin(UniverSheetsUIPlugin); univer.registerPlugin(UniverDocsPlugin); univer.registerPlugin(UniverDocsUIPlugin); univer.registerPlugin(UniverSheetsFormulaPlugin); univer.registerPlugin(UniverSheetsFormulaUIPlugin); univer.registerPlugin(UniverSheetsNumfmtPlugin); univer.registerPlugin(UniverSheetsNumfmtUIPlugin); univer.createUnit(UniverInstanceType.UNIVER_SHEET, {}); const univerAPI = FUniver.newAPI(univer); </script> </body>

表格基本操作

在上一小节的代码中,你已经创建了一个 Univer 实例并创建了一个空的电子表格,不过大部分情况下你可能需要的是在 Univer 当中加载已有数据。这一小节将会介绍如何向 Univer 加载数据、修改数据以及如何从 Univer 中存储数据。

加载数据

通过调用 univerAPIcreateUniverSheet 方法,可以创建一个新的 Workbook 实例。方法的第一个参数是一个对象,包含了 Workbook 的数据,应该符合 IWorkbookData 接口。

import { IWorkbookData, LocaleType } from "@univerjs/core"; const data: IWorkbookData = { id: 'test', sheets: { sheet1: { id: 'sheet1', name: 'sheet1', cellData: { 0: { 0: { v: 'Hello Univer!', }, }, }, rowCount: 100, columnCount: 100, }, }, locale: LocaleType.ZH_CN, name: 'Test Workbook', sheetOrder: ['sheet1'], }; const workbook = univerAPI.createWorkbook(data);

你可以在 工作表数据结构 进一步了解如何初始化表格数据。

修改数据

你可以通过调用 univerAPI 的方法来使用 Univer 了,例如获取当前激活的,并在指定的范围更新值:

const sheet = univerAPI.getActiveWorkbook().getActiveSheet(); const range = sheet.getRange(0, 0, 1, 1); range.setValue(1);
🚨

Univer 基于 命令系统 对状态和数据进行操作和更新,因此你必须使用 Facade API(或其对应的命令)来更新数据,任何直接对数据进行修改以更新视图的操作都不会生效。

存储数据

通过调用 workbooksave 方法,可以得到 IWorkbookData 对象,包含表格内部的最新数据。

const savedData = univerAPI.getActiveWorkbook().save();

下一步

  • 基础概念 章节了解本章中出现的插件、命令和 Facade API 等概念。
  • 工作表数据结构 进一步了解如何初始化表格数据。
  • 功能 相关章节中了解修改电子表格数据的所有操作。

Footnotes

  1. https://blog.npmjs.org/post/110924823920/npm-weekly-5

  2. https://pnpm.io/npmrc#auto-install-peers

  3. https://github.com/yarnpkg/yarn/issues/1503


这个页面对您有帮助吗?
Last updated on