跳到主要内容

React

ONLYOFFICE 文档 React 组件 将ONLYOFFICE 文档集成到 React 项目。该组件支持 React 16.9 及更高版本,包括 React 19。每个版本的更改列表发布在 Releases 选项卡中。

先决条件

此过程需要 Node.js (和 npm) 以及一个正在运行的 ONLYOFFICE 文档实例。如果您还没有,请按照自托管部分的说明将其安装在您自己的服务器上,或将其部署在云端

此过程还需要您的 ONLYOFFICE 文档的密钥。编辑器配置将使用以该密钥签名的 JSON Web Token 进行校验,并且该校验默认处于启用状态。请参阅签名配置

本页假定您具备 React 的基本使用知识。该组件可用于任何 React 项目。以下步骤使用 Vite 从头创建一个项目。

使用 ONLYOFFICE 文档编辑器创建演示 React 应用程序

此过程创建一个基本 React 应用程序,并在其中安装 ONLYOFFICE 文档编辑器。

  1. 创建一个名为 onlyoffice-react-demo 的新 React 项目并安装其依赖项:

    npm create vite@latest onlyoffice-react-demo -- --template react
    cd onlyoffice-react-demo
    npm install
  2. npm 公共注册表安装 ONLYOFFICE 文档 React 组件,以及用于对编辑器配置进行签名的 jsonwebtoken 包,并将它们保存到 package.json 文件中。

    TypeScript 类型声明来自 @onlyoffice/doceditor-types 对等依赖项,npm 7 及更高版本会自动安装该依赖项,而 yarn 不会。jsonwebtoken 包仅在开发服务器中运行,因此它是演示应用程序的开发依赖项。在生产应用程序中,它属于对配置进行签名的后端。

    npm install --save @onlyoffice/document-editor-react
    npm install --save-dev jsonwebtoken
  3. 替换 onlyoffice-react-demo 项目中 ./src/App.jsx./vite.config.js 文件的内容,并创建 ./.env.local 文件:

    App 组件,它在挂载时请求已签名的配置,并在配置到达后渲染 ONLYOFFICE 文档编辑器。config 属性为必填项,因此在此之前该组件将返回 null

    编辑器会填满其渲染所在的元素,因此外层容器为其设置了明确的高度。

    import {DocumentEditor} from "@onlyoffice/document-editor-react";
    import {useEffect, useState} from "react";

    function onDocumentReady() {
    console.log("Document is loaded");
    }

    function onLoadComponentError(errorCode, errorDescription) {
    switch (errorCode) {
    case -1: // Unknown error loading component
    console.log(errorDescription);
    break;

    case -2: // Error load DocsAPI from documentServerUrl
    console.log(errorDescription);
    break;

    case -3: // DocsAPI is not defined
    console.log(errorDescription);
    break;
    }
    }

    export default function App() {
    const [config, setConfig] = useState(null);

    useEffect(() => {
    fetch("/api/editor-config")
    .then((response) => response.json())
    .then(setConfig);
    }, []);

    if (!config) return null; // 配置尚未加载

    return (
    <div style={{display: "flex", height: "100svh"}}>
    <DocumentEditor
    id="docxEditor"
    documentServerUrl={import.meta.env.VITE_DOCUMENT_SERVER_URL}
    config={config}
    events_onDocumentReady={onDocumentReady}
    onLoadComponentError={onLoadComponentError}
    />
    </div>
    )
    }
  4. onlyoffice-react-demo 目录中启动 Vite 开发服务器:

    npm run dev

    在浏览器中打开 http://localhost:5173。编辑器将打开已签名配置中的文档,并且 events_onDocumentReady 处理程序会在浏览器控制台中输出 Document is loaded

签名配置

ONLYOFFICE 文档使用 JSON Web Token 校验编辑器配置。JWT 验证默认处于启用状态,因此 config 必须包含 token,即配置本身的签名。该令牌不是固定值:每当任何已签名的参数发生变化时,都必须重新生成它。

签名需要使用 ONLYOFFICE 文档的密钥,因此请在您的服务器上生成令牌,并将已就绪的配置发送到浏览器。React 应用程序无法确保密钥不被泄露。

组件会将 config 合并到发送给 ONLYOFFICE 文档的配置中,因此 token 字段会原样传递给编辑器。

上述演示应用程序在 Vite 开发服务器中对配置进行签名,而该服务器仅存在于开发环境中。在生产应用程序中,请将相同的代码移至您的后端,并保留该接口路径,因为组件请求配置的方式完全相同。

有关其他语言的签名代码,请参阅签名部分。

在 React 组件中调用编辑器方法

组件会将每个编辑器实例存储在 window.DocEditor.instances 对象中。请通过组件 id 获取实例,然后从该实例调用任何编辑器方法

function onDocumentReady() {
const documentEditor = window.DocEditor.instances["docxEditor"];

documentEditor.showMessage("Welcome to ONLYOFFICE Editor!");
}

在 React 中使用自动化 API

自动化 API 通过连接器从您自己的界面与文档内容进行交互。连接器与创建它的编辑器实例绑定,只要该实例存在,连接器就保持有效。

信息

自动化 API 仅适用于 ONLYOFFICE 文档开发者版

请在 events_onDocumentReady 处理程序中使用 createConnector 方法创建连接器,并重复使用它,而不要为每次操作都创建新的连接器。请将其保存在 ref 中以便清理,并保存在 state 中以供使用它的组件访问:

import {DocumentEditor} from "@onlyoffice/document-editor-react";
import {useEffect, useRef, useState} from "react";

export default function Editor({config}) {
const [connector, setConnector] = useState(null);
const connectorRef = useRef(null);

const onDocumentReady = () => {
const documentEditor = window.DocEditor.instances["docxEditor"];
const created = documentEditor.createConnector();

connectorRef.current = created; // 用于清理
setConnector(created); // 供使用连接器的组件访问
};

useEffect(() => {
return () => {
connectorRef.current?.disconnect();
connectorRef.current = null;
};
}, []);

return (
<div style={{display: "flex", height: "100svh"}}>
<DocumentEditor
id="docxEditor"
documentServerUrl="http://documentserver/"
config={config}
events_onDocumentReady={onDocumentReady}
/>
</div>
)
}

请在渲染 DocumentEditor 的组件的清理函数中调用 disconnect 方法,以便在编辑器仍然存在时断开连接器。

请在通过连接器发送命令之前检查连接器是否已创建,而不是重试失败的调用:

useEffect(() => {
if (!connector) return; // 编辑器尚未准备就绪

connector.executeMethod("GetAllComments", null, (comments) => {
console.log("Comments:", comments);
});
}, [connector]);

executeMethod 按名称运行单个编辑器方法,如上所示。callCommand 在编辑器内部运行一个包含 Office JavaScript API 命令的函数,文档内容正是通过这种方式进行修改的。该函数拥有自身的上下文,无法读取组件状态,因此请通过 Asc.scope 对象传递它所需的数据:

function insertText(text) {
if (!connector) return;

Asc.scope.text = text; // 下面的命令拥有自身的上下文

connector.callCommand(() => {
const document = Api.GetDocument();
const paragraph = Api.CreateParagraph();

paragraph.AddText(Asc.scope.text);
document.InsertContent([paragraph]);
}, () => {
console.log("Text is inserted");
});
}
备注

当组件被卸载时,以及当 documentServerUrlconfigdocument_fileTypedocument_titledocumentTypeeditorConfig_langheighttypewidth 属性发生更改时,组件会销毁编辑器,然后加载新的编辑器。已销毁编辑器的连接器将失效:请断开该连接器,并在新编辑器的 events_onDocumentReady 处理程序中创建新的连接器。

部署演示 React 应用程序

备注

/api/editor-config 接口是 Vite 开发服务器的一部分,因此它不存在于生产版本中。请按照签名配置中的说明,从您自己的后端提供该接口,并保留 App.jsx 所请求的路径。

onlyoffice-react-demo 目录中创建生产版本,并使用 Vite 预览服务器在本地检查该版本:

npm run build
npm run preview

生产版本将生成在 dist 目录中。要将应用程序部署到您自己的 Web 服务器,请将该目录的内容复制到 Web 服务器的根目录。

将组件与 Next.js 结合使用

组件在浏览器中渲染编辑器,并且不包含 "use client" 指令。编辑器配置中还包含事件处理函数,而这些函数无法从服务器组件传递。因此,请从客户端组件渲染该组件。

在 App Router 中,请在服务器上运行的路由处理程序中对配置进行签名,并从客户端组件请求该配置:

客户端组件,它带有 "use client" 指令,请求已签名的配置,并在配置到达后渲染编辑器。

"use client";

import {DocumentEditor} from "@onlyoffice/document-editor-react";
import {useEffect, useState} from "react";

export default function Editor() {
const [config, setConfig] = useState(null);

useEffect(() => {
fetch("/api/editor-config")
.then((response) => response.json())
.then(setConfig);
}, []);

if (!config) return null;

return (
<div style={{display: "flex", height: "100svh"}}>
<DocumentEditor
id="docxEditor"
documentServerUrl="http://documentserver/"
config={config}
events_onDocumentReady={() => console.log("Document is loaded")}
/>
</div>
)
}

服务器组件也可以构建配置并将其作为属性传递给客户端组件,但事件处理程序仍需保留在客户端组件中:函数无法从服务器组件传递。

服务器端渲染不需要任何额外设置:组件在服务器上渲染一个空容器,并在水合后加载 ONLYOFFICE 文档 API 脚本。只有在需要将组件完全排除在预渲染之外时,才需要使用 next/dynamic{ssr: false} 选项导入组件。在 App Router 中,该选项仅在客户端组件中可用。

要部署应用程序,请使用 next start 命令。使用 output: "export" 选项的静态版本无法运行路由处理程序,因此需要由单独的后端提供该接口。

属性

config 属性会覆盖组件的各个单独属性。该合并为浅层合并:config 的顶层键会完整替换相应的组件属性,而不是与其合并。

  • 如果设置了 config.document,则 document_fileTypedocument_title 属性将被忽略。
  • 如果设置了 config.editorConfig,则 editorConfig_lang 属性将被忽略。
  • 如果设置了 config.events,则所有 events_on* 属性都将被忽略。

每个 events_on* 属性都对应编辑器配置中同名的事件

名称类型默认描述
id*string-组件唯一标识符。
documentServerUrl*string-ONLYOFFICE 文档服务器的地址。
config*object-用于打开文件的通用配置对象
shardkeystring | booleantrue添加到 ONLYOFFICE 文档 API 脚本请求查询字符串中的 shardkey 参数,用于负载均衡。如果设置为 true,则使用 config 中的文档 key 作为其值。设置为 false 可在发送请求时不带此参数。
onLoadComponentError(errorCode: number, errorDescription: string) => voidnull加载组件时发生错误时调用的函数。
document_fileTypestringnull文件的类型。
document_titlestringnull文件名。
documentTypestringnull文档类型。
editorConfig_langstringnull编辑器界面语言
heightstringnull浏览器窗口中的文档高度。
typestringnull用于访问文档的平台类型:desktopmobileembedded
widthstringnull浏览器窗口中的文档宽度。
events_onAppReady(event: object) => voidnull当应用程序加载到浏览器中时调用的函数。
events_onDocumentStateChange(event: object) => voidnull修改文档时调用的函数。
events_onMetaChange(event: object) => voidnull通过 meta 命令更改文档的元信息时调用的函数。
events_onDocumentReady(event: object) => voidnull将文档加载到文档编辑器时调用的函数。
events_onInfo(event: object) => voidnull应用程序打开文件时调用的函数。
events_onWarning(event: object) => voidnull发生警告时调用的函数。
events_onError(event: object) => voidnull发生错误或其他特定事件时调用的函数。
events_onRequestSharingSettings(event: object) => voidnull当用户尝试通过单击更改访问权限按钮来管理文档访问权限时调用的函数。
events_onRequestRename(event: object) => voidnull当用户尝试通过单击重命名... 按钮重命名文件时调用的函数。
events_onRequestInsertImage(event: object) => voidnull当用户尝试通过单击来自存储的图像按钮插入图像时调用的函数。
events_onRequestSaveAs(event: object) => voidnull当用户尝试通过单击**另存为...**按钮来保存文件时调用的函数。
events_onRequestMailMergeRecipients(event: object) => voidnull自 7.5 版起已弃用,请改用 events_onRequestSelectSpreadsheet。当用户尝试通过单击邮件合并 按钮来选择收件人数据时调用的函数。
events_onRequestCompareFile(event: object) => voidnull自 7.5 版起已弃用,请改用 events_onRequestSelectDocument。当用户尝试通过单击存储中的文档按钮来选择要比较的文档时调用的函数。
events_onRequestEditRights(event: object) => voidnull当用户尝试通过单击编辑文档按钮将文档从查看模式切换到编辑模式时调用的函数。
events_onRequestHistory(event: object) => voidnull当用户尝试通过单击版本历史记录按钮来显示文档版本历史记录时调用的函数。
events_onRequestHistoryClose(event: object) => voidnull当用户试图通过单击关闭历史记录按钮从查看文档版本历史记录返回到文档时调用的函数。
events_onRequestHistoryData(event: object) => voidnull当用户试图单击文档版本历史记录中的特定文档版本时调用的函数。
events_onRequestRefreshFile(event: object) => voidnull当必须在不重新加载页面的情况下更新编辑器中的文件时调用的函数。
events_onRequestRestore(event: object) => voidnull当用户尝试通过单击版本历史记录中的恢复按钮来恢复文件版本时调用的函数。
events_onRequestSelectSpreadsheet(event: object) => voidnull当用户尝试通过单击邮件合并按钮来选择收件人数据时调用的函数。
events_onRequestSelectDocument(event: object) => voidnull当用户尝试选择文档以进行比较、合并或插入文本时调用的函数。
events_onRequestUsers(event: object) => voidnull当用户可以选择要在评论中提及的其他用户、授予编辑特定工作表区域的访问权限或设置用户头像时调用的函数。

* - 必填字段

反馈和支持

如果您对 ONLYOFFICE 文档 React 组件有任何问题、疑问或建议,请参阅问题部分。