安装和基本使用
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 将会非常简单。我们推荐使用 Vite、esbuild 或 Webpack 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.createUniverSheet({ 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.createUniverSheet({ 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 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, FUniver } from "@univerjs/core";
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/dist/bundles/rxjs.umd.min.js"></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/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, FUniver } = UniverCore
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 中存储数据。
加载数据
通过调用 univerAPI
的 createUniverSheet
方法,可以创建一个新的 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.createUniverSheet(data);
你可以在 工作表数据结构 进一步了解如何初始化表格数据。
修改数据
你可以通过调用 univerAPI
的方法来使用 Univer 了,例如获取当前激活的,并在指定的范围更新值:
const sheet = univerAPI.getActiveWorkbook().getActiveSheet();
const range = sheet.getRange(0, 0, 1, 1);
range.setValue(1);
Univer 基于 命令系统 对状态和数据进行操作和更新,因此你必须使用 Facade API(或其对应的命令)来更新数据,任何直接对数据进行修改以更新视图的操作都不会生效。
存储数据
通过调用 workbook
的 save
方法,可以得到 IWorkbookData
对象,包含表格内部的最新数据。
const savedData = univerAPI.getActiveWorkbook().save();