协同编辑

请从协同集成开始,依次跑通示例、接入业务、验证持久化和权限。具体实现及可运行的 Web/Server 示例统一维护在 协同快速开始中。

先由经过认证的业务 API 调用 Collaboration Service 创建 Unit,再在浏览器中加载返回的标识。按快速开始一起配置 HTTP、Session Ticket 和 WebSocket 入口,通过 Database Adapter 持久化,并用服务端 Middleware分别校验读取、JOIN 和修改权限。

使用这些 API 前,请先确认目标服务端支持 PDF Unit;Sheets 协同示例运行成功不能证明 PDF 已受支持。

加载协作 PDF

通过服务器 API 或 importPdfToUnitIdAsync 创建 PDF 单元后,使用协作 Facade 加载:

先设置当前用户,再加载文档;详见协同集成。

TypeScript
import { UserManagerService } from '@univerjs/core'import '@univerjs-pro/collaboration-client/facade'univer.__getInjector().get(UserManagerService).setCurrentUser({ userID, name, avatar })const pdf = await univerAPI.getCollaboration().loadPdfAsync(unitId)if (!pdf) {  throw new Error(`PDF unit not found: ${unitId}`)}console.log(pdf.getId(), pdf.getName())

loadPdfAsync 会加载服务器快照、准备协作会话并返回 FPdf。当单元无法关联到 PDF 时,它会返回 null。

通过同步状态、重发与冲突恢复实现保存提示,并在刷新前保护尚未确认的修改。

移除内置 URL 加载协同文档

注意事项

从 1.2.0 版本开始,Univer 移除了内置的 URL 协同文档加载逻辑,不再自动读取 URL 中的 unit 和 type 参数来加载协同文档。

如果你的应用依赖这一行为,可以通过自定义插件恢复。

接入自定义插件

将下方四个文件按以下目录结构复制到项目中:

text
custom-url-load/├── plugin.ts├── controllers/│   └── data-loader.controller.ts└── services/    ├── url.service.ts    └── web-url.service.ts

在完成编辑器和协同插件初始化后,先设置当前用户,再注册 CustomUrlLoadPlugin。

TypeScript
import { UserManagerService } from '@univerjs/core'import { CustomUrlLoadPlugin } from './custom-url-load/plugin'univer.__getInjector().get(UserManagerService).setCurrentUser({ userID, name, avatar })univer.registerPlugin(CustomUrlLoadPlugin)

注册该插件后,由插件负责加载文档,无需再为同一文档调用 loadPdfAsync()。如果应用已经通过 Facade 加载文档,可以继续使用上一节的方式,并根据业务需要自行处理 URL。

完整插件代码

TypeScript
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client'import { DependentOn, Inject, Injector, Plugin } from '@univerjs/core'import { CollaborationDataLoaderController } from './controllers/data-loader.controller'import { IURLService } from './services/url.service'import { WebURLService } from './services/web-url.service'@DependentOn(UniverCollaborationClientPlugin)export class CustomUrlLoadPlugin extends Plugin {  static override pluginName = 'CUSTOM_URL_LOAD_PLUGIN'  constructor(    _config: undefined,    @Inject(Injector) protected override readonly _injector: Injector  ) {    super()  }  override onStarting(): void {    this._injector.add([IURLService, { useClass: WebURLService }])    this._injector.add([CollaborationDataLoaderController])    this.disposeWithMe(this._injector.get(IURLService))    this.disposeWithMe(this._injector.get(CollaborationDataLoaderController))  }}

你觉得这篇文档如何?

© 2026 DreamNum Co., Ltd.