Angular
ONLYOFFICE 文档 Angular 组件将 ONLYOFFICE 文档集成到 Angular 项目。每个版本的更改列表发布在 Releases 选项卡中。
先决条件
此过程需要 Node.js(和 npm) 20.6 或更高版本,以及一个正在运行的 ONLYOFFICE 文档实例。如果您还没有,请按照自托管部分的说明将其安装在您自己的服务器上,或将其部署在云端。
此过程还需要您的 ONLYOFFICE 文档的密钥。编辑器配置将使用以该密钥签名的 JSON Web Token 进行校验,并且该校验默认处于启用状态。请参阅签名配置。
本页假定您具备 Angular 的基本使用知识。
该组件为每个 Angular 主版本发布一个独立的主版本:
| 组件版本 | Angular 版本 |
|---|---|
| 9.x | 22 |
| 8.x | 21 |
| 7.x | 20 |
| 6.x | 19 |
| 5.x | 18 |
| 4.x | 17 |
请安装与您项目的 Angular 版本相匹配的组件版本。
使用 ONLYOFFICE 文档编辑器创建演示 Angular 应用程序
此过程创建一个基本 Angular 应用程序,并在其中安装 ONLYOFFICE 文档编辑器。
-
打开命令行或命令提示符,安装 Angular CLI 包,并创建一个名为
onlyoffice-angular-demo的新 Angular 项目:npm install -g @angular/cling new --defaults --skip-git onlyoffice-angular-democd onlyoffice-angular-demo -
从 npm 公共注册表安装 ONLYOFFICE 文档 Angular 组件,以及用于对编辑器配置进行签名的 jsonwebtoken 包和用于启动签名服务器的 concurrently 包,并将它们保存到
package.json文件中。TypeScript 类型声明来自
@onlyoffice/doceditor-types对等依赖项,npm 7 及更高版本会自动安装该依赖项,而 yarn 不会。jsonwebtoken和concurrently包仅在演示应用程序中运行,因此它们都是开发依赖项。在生产应用程序中,jsonwebtoken属于对配置进行签名的后端。- npm
- yarn
npm install --save @onlyoffice/document-editor-angularnpm install --save-dev jsonwebtoken concurrentlyyarn add @onlyoffice/document-editor-angularyarn add -D @onlyoffice/doceditor-types jsonwebtoken concurrently -
替换
onlyoffice-angular-demo项目中./src/app/app.ts和./src/app/app.html文件的内容,并创建其余文件:- src/app/app.ts
- src/app/app.html
- server.mjs
- proxy.conf.json
- package.json
- .env.local
App组件,该组件在初始化时请求已签名的配置,并在配置到达后渲染 ONLYOFFICE 文档编辑器。import {Component, OnInit} from "@angular/core";import {type Config} from "@onlyoffice/doceditor-types";import {DocumentEditorModule} from "@onlyoffice/document-editor-angular";@Component({selector: "app-root",imports: [DocumentEditorModule],templateUrl: "./app.html",})export class App implements OnInit {config: Config | null = null;async ngOnInit() {const response = await fetch("/api/editor-config");this.config = await response.json();}onDocumentReady = () => {console.log("Document is loaded");};onLoadComponentError = (errorCode: number, errorDescription: string) => {switch (errorCode) {case -1: // Unknown error loading componentconsole.log(errorDescription);break;case -2: // Error load DocsAPI from documentServerUrlconsole.log(errorDescription);break;case -3: // DocsAPI is not definedconsole.log(errorDescription);break;}};}App组件的模板。config属性为必填项,因此@if会在配置加载完成之前将编辑器排除在模板之外。编辑器会填满其渲染所在的元素,因此外层容器为其设置了明确的高度。
请将
http://documentserver/替换为您的服务器的地址,该地址与.env.local中的DOCUMENT_SERVER_URL相同;您可以注册一个免费的 ONLYOFFICE 云,并使用其公共 IP 地址或公共 DNS,这些地址或 DNS 可以在云控制台的实例部分找到。<div style="display: flex; height: 100svh">@if (config) {<document-editorid="docxEditor"documentServerUrl="http://documentserver/"[config]="config"[events_onDocumentReady]="onDocumentReady"[onLoadComponentError]="onLoadComponentError"></document-editor>}</div>签名服务器,它代替您的后端:配置在 Node.js 中构建并签名,只有已签名的配置才会发送到浏览器。
警告请将
https://static.onlyoffice.com/assets/docs/samples/demo.docx替换为您的文件的 URL,或保留我们示例文档的 URL 以进行测试。警告key标识文档的版本,而不是编辑会话:打开相同key的所有用户共享同一个会话,并且具有已知key的文档会直接从缓存中提供。该演示应用程序始终使用同一个key,因为示例文档不会发生变化。每当文档被编辑并保存后,请生成新的 key,否则编辑器将继续提供缓存中的版本。import {createServer} from "node:http";import jwt from "jsonwebtoken";const documentServerUrl = process.env.DOCUMENT_SERVER_URL;createServer((request, response) => {const config = {document: {fileType: "docx",key: "Khirz6zTPdfd7",title: "Example Document Title.docx",url: "https://static.onlyoffice.com/assets/docs/samples/demo.docx",},documentType: "word",editorConfig: {callbackUrl: documentServerUrl + "dummyCallback",},};config.token = jwt.sign(config, process.env.DOCUMENT_SERVER_SECRET, {algorithm: "HS256"});response.setHeader("Content-Type", "application/json");response.end(JSON.stringify(config));}).listen(3000);代理配置,它使开发服务器将配置请求转发到签名服务器。
{"/api/editor-config": {"target": "http://localhost:3000","secure": false}}请在
./angular.json文件中该项目的serve目标下引用该文件:{// ..."projects": {"onlyoffice-angular-demo": {// ..."architect": {// ..."serve": {// ..."options": {"proxyConfig": "proxy.conf.json"}}}}}}请将
start脚本替换为以下内容,它会同时启动签名服务器和 Angular CLI 开发服务器。{// ..."scripts": {// ..."start": "concurrently \"node --env-file=.env.local server.mjs\" \"ng serve\"",// ...}}您的 ONLYOFFICE 文档的地址及其密钥,二者均由
server.mjs读取。该地址以斜杠结尾,因为签名服务器会在其后追加dummyCallback。请将该文件添加到
.gitignore,因为 Angular CLI 不会忽略它。DOCUMENT_SERVER_URL=http://documentserver/DOCUMENT_SERVER_SECRET=your-secret-key备注以上步骤使用独立组件,Angular CLI 默认生成此类组件。如果您的项目仍然基于 NgModule,请改为将
DocumentEditorModule添加到根模块文件中@NgModule装饰器的imports属性,而不是@Component装饰器。 -
在
onlyoffice-angular-demo目录中同时启动签名服务器和 Angular CLI 开发服务器:npm run start在浏览器中打开
http://localhost:4200。编辑器将打开已签名配置中的文档,并且events_onDocumentReady处理程序会在浏览器控制台中输出Document is loaded。
签名配置
ONLYOFFICE 文档使用 JSON Web Token 校验编辑器配置。JWT 验证默认处于启用状态,因此 config 必须包含 token,即配置本身的签名。该令牌不是固定值:每当任何已签名的参数发生变化时,都必须重新生成它。
签名需要使用 ONLYOFFICE 文档的密钥,因此请在您的服务器上生成令牌,并将已就绪的配置发送到浏览器。Angular 应用程序无法确保密钥不被泄露。
组件会将 config 合并到发送给 ONLYOFFICE 文档的配置中,因此 token 字段会原样传递给编辑器。
上述演示应用程序在与开发服务器并行运行的 Node.js 服务器中对配置进行签名。在生产应用程序中,请将相同的代码移至您的后端,并保留该接口路径,因为组件请求配置的方式完全相同。
有关其他语言的签名代码,请参阅签名部分。
在 Angular 组件中调用编辑器方法
组件会将每个编辑器实例存储在 window.DocEditor.instances 对象中。请通过组件 id 获取实例,然后从该实例调用任何编辑器方法:
export class App implements OnInit {
// ...
onDocumentReady = () => {
const documentEditor = window.DocEditor.instances["docxEditor"];
documentEditor.showMessage("Welcome to ONLYOFFICE Editor!");
};
}
该包已声明 window 对象的 DocEditor 属性,因此无需额外的 TypeScript 声明。
在 Angular 中使用自动化 API
自动化 API 通过连接器从您自己的界面与文档内容进行交互。连接器与创建它的编辑器实例绑定,只要该实例存在,连接器就保持有效。
自动化 API 仅适用于 ONLYOFFICE 文档开发者版。
请在 events_onDocumentReady 处理程序中使用 createConnector 方法创建连接器,并重复使用它,而不要为每次操作都创建新的连接器。请将其保存在渲染 document-editor 的组件的字段中:
import {Component, OnDestroy} from "@angular/core";
import {type Config} from "@onlyoffice/doceditor-types";
import {DocumentEditorModule} from "@onlyoffice/document-editor-angular";
@Component({
selector: "app-root",
imports: [DocumentEditorModule],
templateUrl: "./app.html",
})
export class App implements OnDestroy {
config: Config = {
document: {
fileType: "docx",
key: "Khirz6zTPdfd7",
title: "Example Document Title.docx",
url: "https://example.com/url-to-example-document.docx",
},
documentType: "word",
editorConfig: {
callbackUrl: "https://example.com/url-to-callback",
},
};
connector: any = null;
onDocumentReady = () => {
const documentEditor = window.DocEditor.instances["docxEditor"];
this.connector = documentEditor.createConnector();
};
ngOnDestroy() {
this.connector?.disconnect();
this.connector = null;
}
}
请在渲染 document-editor 的组件的 ngOnDestroy 钩子中调用 disconnect 方法,以便在编辑器仍然存在时断开连接器。
请在通过连接器发送命令之前检查连接器是否已创建,而不是重试失败的调用:
export class App implements OnDestroy {
// ...
getAllComments() {
if (!this.connector) return; // 编辑器尚未准备就绪
this.connector.executeMethod("GetAllComments", null, (comments: object[]) => {
console.log("Comments:", comments);
});
}
}
executeMethod 按名称运行单个编辑器方法,如上所示。callCommand 在编辑器内部运行一个包含 Office JavaScript API 命令的函数,文档内容正是通过这种方式进行修改的。该函数拥有自身的上下文,无法读取组件状态,因此请通过 Asc.scope 对象传递它所需的数据:
export class App implements OnDestroy {
// ...
insertText(text: string) {
if (!this.connector) return;
Asc.scope.text = text; // 下面的命令拥有自身的上下文
this.connector.callCommand(() => {
const document = Api.GetDocument();
const paragraph = Api.CreateParagraph();
paragraph.AddText(Asc.scope.text);
document.InsertContent([paragraph]);
}, () => {
console.log("Text is inserted");
});
}
}
Asc 来自 ONLYOFFICE 文档 API 脚本,而 Api 仅存在于运行该命令的编辑器内部。请在项目的 .d.ts 文件中声明这两者:
declare const Asc: {scope: Record<string, unknown>};
declare const Api: any;
当属性更改导致组件销毁编辑器并加载新的编辑器时(详见属性部分),已销毁编辑器的连接器将失效:请断开该连接器,并在新编辑器的 events_onDocumentReady 处理程序中创建新的连接器。
部署演示 Angular 应用程序
proxy.conf.json 文件仅配置开发服务器,因此生产版本无法访问签名服务器。请按照签名配置中的说明,从您自己的后端提供 /api/editor-config 接口,并保留 app.ts 所请求的路径。
在 onlyoffice-angular-demo 目录中创建生产版本,并使用开发服务器的生产配置在本地检查该版本:
ng build
ng serve --configuration production
生产版本将生成在 dist/onlyoffice-angular-demo/browser 目录中。要将应用程序部署到您自己的 Web 服务器,请将该目录的内容复制到 Web 服务器的根目录。
如需为开发版本和生产版本使用不同的设置(例如不同的文档服务器地址),请按照 Angular environments 指南配置构建目标。
属性
config 属性会覆盖组件的各个单独属性。该合并为浅层合并:config 的顶层键会完整替换相应的组件属性,而不是与其合并。
- 如果设置了
config.document,则document_fileType和document_title属性将被忽略。 - 如果设置了
config.editorConfig,则editorConfig_lang属性将被忽略。 - 如果设置了
config.events,则所有events_on*属性都将被忽略。
每个 events_on* 属性都对应编辑器配置中同名的事件。
当 config、document_fileType、document_title、documentType、editorConfig_lang、height、type 或 width 属性发生更改时,组件会销毁编辑器并加载新的编辑器;当组件被卸载时,组件会销毁编辑器。
| 名称 | 类型 | 默认 | 描述 |
|---|---|---|---|
id* | string | - | 组件唯一标识符。 |
documentServerUrl* | string | - | ONLYOFFICE 文档服务器的地址。 |
config* | object | - | 用于打开文件的通用配置对象。 |
shardkey | string | boolean | true | 添加到 ONLYOFFICE 文档 API 脚本请求查询字符串中的 shardkey 参数,用于负载均衡。如果设置为 true,则使用 config 中的文档 key 作为其值。设置为 false 可在发送请求时不带此参数。 |
onLoadComponentError | (errorCode: number, errorDescription: string) => void | null | 加载组件时发生错误时调用的函数。 |
document_fileType | string | null | 文件的类型。 |
document_title | string | null | 文件名。 |
documentType | string | null | 文档类型。 |
editorConfig_lang | string | null | 编辑器界面语言。 |
height | string | null | 浏览器窗口中的文档高度。 |
type | string | null | 用于访问文档的平台类型:desktop、mobile 或 embedded。 |
width | string | null | 浏览器窗口中的文档宽度。 |
events_onAppReady | (event: object) => void | null | 当应用程序加载到浏览器中时调用的函数。 |
events_onDocumentStateChange | (event: object) => void | null | 修改文档时调用的函数。 |
events_onMetaChange | (event: object) => void | null | 通过 meta 命令更改文档的元信息时调用的函数。 |
events_onDocumentReady | (event: object) => void | null | 将文档加载到文档编辑器时调用的函数。 |
events_onInfo | (event: object) => void | null | 应用程序打开文件时调用的函数。 |
events_onWarning | (event: object) => void | null | 发生警告时调用的函数。 |
events_onError | (event: object) => void | null | 发生错误或其他特定事件时调用的函数。 |
events_onRequestSharingSettings | (event: object) => void | null | 当用户尝试通过单击更改访问权限按钮来管理文档访问权限时调用的函数。 |
events_onRequestRename | (event: object) => void | null | 当用户尝试通过单击重命名... 按钮重命名文件时调用的函数。 |
events_onMakeActionLink | (event: object) => void | null | 当用户试图获取打开包含书签的文档的链接时调用的函数,滚动到书签位置。 |
events_onRequestInsertImage | (event: object) => void | null | 当用户尝试通过单击来自存储的图像按钮插入图像时调用的函数。 |
events_onRequestSaveAs | (event: object) => void | null | 当用户尝试通过单击另存为... 按钮来保存文件时调用的函数。 |
events_onRequestMailMergeRecipients | (event: object) => void | null | 自 7.5 版起已弃用,请改用 events_onRequestSelectSpreadsheet。当用户尝试通过单击邮件合并按钮来选择收件人数据时调用的函数。 |
events_onRequestCompareFile | (event: object) => void | null | 自 7.5 版起已弃用,请改用 events_onRequestSelectDocument。当用户尝试通过单击存储中的文档按钮来选择要比较的文档时调用的函数。 |
events_onRequestEditRights | (event: object) => void | null | 当用户尝试通过单击编辑文档按钮将文档从查看模式切换到编辑模式时调用的函数。 |
events_onRequestHistory | (event: object) => void | null | 当用户尝试通过单击版本历史记录按钮来显示文档版本历史记录时调用的函数。 |
events_onRequestHistoryClose | (event: object) => void | null | 当用户试图通过单击关闭历史记录按钮从查看文档版本历史记录返回到文档时调用的函数。 |
events_onRequestHistoryData | (event: object) => void | null | 当用户试图单击文档版本历史记录中的特定文档版本时调用的函数。 |
events_onRequestRestore | (event: object) => void | null | 当用户尝试通过单击版本历史记录中的恢复按钮来恢复文件版本时调用的函数。 |
events_onRequestSelectSpreadsheet | (event: object) => void | null | 当用户尝试通过单击邮件合并按钮来选择收件人数据时调用的函数。 |
events_onRequestSelectDocument | (event: object) => void | null | 当用户尝试选择文档以进行比较、合并或插入文本时调用的函数。 |
events_onRequestUsers | (event: object) => void | null | 当用户可以选择要在评论中提及的其他用户、授予编辑特定工作表区域的访问权限或设置用户头像时调用的函数。 |
* - 必填字段
反馈和支持
如果您对 ONLYOFFICE 文档 Angular 组件有任何问题、疑问或建议,请参阅问题部分。