OnlyOffice 使用笔记
官方文档: https://api.onlyoffice.com/zh/editors/basic
基本概念
是开源的 Office 套件. 提供了, 编辑查看, 与协作功能.
架构模型中 OnlyOffice 需要一个文档服务器来专门处理 Office. 基本架构模型为:
前端需要使用的 JS 库可以在: https://documentserver/web-apps/apps/api/documents/api.js 中找到
其中 documentserver 为安装了 OnlyOffice 的服务器.
安装 OnlyOffice 的链接为: 官网链接.
可以开了使用 Docker 来安装:
docker pull onlyoffice/documentserver
运行使用
docker run -i -t -d -p 8080:80 --restart=always -e JWT_SECRET=my_jwt_secret -e JWT_ENABLED=false -e ALLOW_PRIVATE_IP_ADDRESS=true onlyoffice/documentserver
这里需要注意的是
JWT_SECRET
, 在 7.2+ 以后, 会使用随机 JWT, 因此在重启后, 会得到不同的 JWT, 因此启动时需要指定秘钥. 如不使用 JWT, 可以设置JWT_ENABLED=false
本地测试环境一般会使用 IP 作为访问, 不要使用
localhost
, 在容器中, 会使用提供的 url 来请求本地服务器的文件与回调地址.localhost
会导致找不到文件, 使用IP
为私有IP
, 因此需要配置ALLOW_PRIVATE_IP_ADDRESS
.另外 OnlyOffice 的默认卷:
/var/log/onlyoffice
存放 ONLYOFFICE Docs 日志./var/www/onlyoffice/Data
存放证书./var/lib/onlyoffice
作为文件缓存目录./var/lib/postgresql
数据库.设置端口映射为
8080
, 然后就可以通过http://localhost:8080/web-apps/apps/api/documents/api.js
来查看代码了:
使用
http://localhost:8080/healthcheck
检查是否可用, 要求返回true
使用步骤
前期准备 (后端)
需要一个本地的后台应用, 用于维护文档, 以及对文档的处理逻辑 (这里使用 Koa 项目来模拟).
原计划使用
dotnet
, 但强类型对JSON
不友好.
mkdir onlyoffice-back-api && cd onlyoffice-back-api
npm init -y
npm i koa koa-body koa-router koa-static
npm i nodemon
然后编写文档
const Koa = require('koa')
const { koaBody } = require('koa-body')
const Router = require('koa-router')
const serve = require("koa-static")
const path = require('path')
const router = new Router()
router.post('/url-to-callback', koaBody(), ctx => {
console.log('body', ctx.request.body)
ctx.body = {
error: 0,
status: 200,
message: 'OK',
success: true
}
})
const app = new Koa()
app.use(serve(path.resolve(__dirname, 'wwwroot')))
app.use(router.routes())
const ser = app.listen(8081)
console.log(`开始监听: `, ser.address())
同时准备 docx
与 xlsx
文件:
前端步骤(基本用法)
- 引入 js 文件, 该文件在 OnlyOffice 服务器上.
- 准备站位标签, 设置
id="placeholder"
. - 准备配置项.
- 编写 JS 代码, 获得
docEditor
详细步骤:
<div id="placeholder"></div>
<script type="text/javascript" src="https://localhost:8080/web-apps/apps/api/documents/api.js"></script>
需要添加相关样式
const config = {
"document": {
"fileType": "docx",
"key": "Khirz6zTPdfd7",
"title": "Example Document Title.docx",
"url": "http://localhost:8081/test.docx"
},
"documentType": "word",
"editorConfig": {
"callbackUrl": "http://localhost:8081/url-to-callback"
}
};
const docEditor = new DocsAPI.DocEditor("placeholder", config);
如果是处理 XLSX
文件, 配置项修改为
const config = {
"document": {
"fileType": "xlsx",
"key": "Khirz6zTPdfd7",
"title": "Example",
"url": "http://localhost:8081/test.xlsx"
},
"documentType": "cell",
"editorConfig": {
"callbackUrl": "http://localhost:8081/url-to-callback"
}
};
运行后即可访问到文档
或者是
后端应用模型
后端需要提供至少三个接口
- 上传文件, 似乎没有看到创建文件的接口. 采用上传的方式添加文件.
- 获得文件的接口, 使用该接口访问文档, 并将其放在
document.url
的位置, 给 OnlyOffice 来展示文档. - 回调接口 (POST) 请求, 在文件发生变化时, OnlyOffice 服务会向该回调接口发送请求, 传递必要信息.
使用 Vue 项目作为客户端
步骤:
- 安装组件
@onlyoffice/document-editor-vue
- 导入组件
import { DocumentEditor } from "@onlyoffice/document-editor-vue"
- 配置数据, 可配置的数据参考 Vue API 文档
必须提供的数据有:
id
唯一标识.documentServerUrl
OnlyOffice 服务地址.config
配置项.
作为一个示例, 使用 vite 构建工具的 vue 模板. 参考代码为:
<script setup lang="ts">
import { DocumentEditor, IConfig } from '@onlyoffice/document-editor-vue'
import { ref } from 'vue';
const config = ref<IConfig>({
document: {
fileType: 'xlsx',
key: 'test123',
title: '电子表格',
url: 'http://192.168.1.102:8081/test.xlsx'
},
documentType: 'cell',
editorConfig: {
callbackUrl: 'http://192.168.1.102:8081/url-to-callback',
mode: 'edit'
}
})
</script>
<template>
<div class="content">
<DocumentEditor
id="docEditor"
documentServerUrl="http://192.168.1.102:8080"
:config="config"
></DocumentEditor>
</div>
</template>
<style scoped>
.content {
width: 80vw;
height: 80vh;
border: 1px dashed blue;
}
</style>
它是如何运作的
整个运行模型涉及三方概念:
- 浏览器应用 (前端应用), 使用
HTTP
请求 与DocumentEditor
来与服务端通信 (包括本地服务端, 和OnlyOffice
服务端). - 本地服务器. 提供文件管理接口, 以及用于
OnlyOffice
回调的接口 (回调响应{ error: 0 }
表示正常). OnlyOffice
文档服务器. 提供 文档编辑服务, 文档命令服务 (附加 API), 文档转换服务, 文档生成器服务, 以及文档编辑器模块 (前端使用).
1. 打开一个文件
实现流程流程
- 用户使用文档管理器 (本地服务提供) 选择需要展示的文件, 获得文件
id
和url
. - 浏览器中的
JavaScript API
(OnlyOffice
提供), 获得文件id
和url
, 来初始化文档编辑器. - 文档编辑器 将文档
id
与url
发送给文档编辑服务, 来打开文档. - 文档编辑服务 使用
id
与url
从文档存储服务 下载文档 (下载到了 文档编辑服务 中), 并将其转换为OpenXML
中间格式. - 准备就绪后, 文档编辑服务将文档返回给浏览器的文档编辑器中.
- 文档编辑器显示文档, 并提供编辑功能. 并实时与文档编辑器服务通信.
实现条件
- 本地服务文档管理接口提供 文件
id
(配置中的key
), 与文件访问的url
(可以是静态url
, 也可以是用接口返回的文件流). - 浏览器使用文档编辑器 (
DocumentEditor
,OnlyOffice
提供). 配置id
(唯一标识, 必须提供), 文档服务器地址 (OnlyOffice
的地址), 以及config
配置.config
配置中提供文件的描述, 以及编辑功能的配置. - 非编辑模式下, 不需要本地后端的
callback
接口响应.
官网提供的流程与图逻辑上是没问题的. 但是隐藏了细节.
- 文档编辑器使用
iframe
迁入到当前页面中, 而iframe
由OnlyOffice
提供.- 完成初始化后, 文档编辑器 (浏览器) 与
OnlyOffice
的文档编辑服务创建ws
信道. 实时进行通信. 而该信道由内部的Node
服务来处理.- 加载文档, 编辑文档等交互操作均通过
ws
信道与OnlyOffice
服务器进行通信.- 保存等行为, 也是将信息通过
ws
传递给OnlyOffice
服务来处理. 在其内部时通过调用相关API
来实现的. 例如打开文档传递了Cmd
信息:
2. 保存文件
官方文档描述很清晰
- 用户在 文档编辑器 中编辑文档.
- 文档编辑器 将变更发送 (实时, 使用
ws
信道) 给 文档编辑服务. - 用户关闭 文档编辑器. 默认情况, 除非配置 强制保存.
- 文档编辑服务 识别到文档工作结束, 将所有变更收集到一个文档中.
- 文档编辑服务 使用 文档编辑器 中配置的
callback
回调url
来通知本地服务器. 并返回修改后的文档url
. - 本地服务器 再通过更新文件的
url
下载文件, 并将文件存储于 文件存储服务 中.
补充: 多人编辑文档时,
callbackUrl
从最后一个加入的用户开始使用的. (有待验证).
3. 共同编辑
- 用户1 和 用户2 在 文档编辑器 中打开同一个文档, 使用
key
来进行唯一标识, 即使同一个url
,key
不同也视为不同的文档. - 假定 用户1 更改了文档 (待验证这个更改是否为实时).
- 文档编辑器 将 用户1 的更新发送到 文档编辑服务.
- 文档编辑服务 将 用户1 的更新发送给 用户2 的 文档编辑器.
- 然后 用户2 即可看到更新.
补充说明
必须使用同一个 key
才表示同一个文件. key
只能使用 0-9, a-z, A-Z, -._=. key
最大长度为128个 字符.
一旦发送保存请求 (status
的值为 2
), 并且本地回调服务响应成功 ({ error: 0 }
). 则该 key
不再允许编辑 (会提示文档已被修改需要重新加载), 但是可以从缓存中查看 (如果存在).
如果用户在编辑完成之前保存文档 (status
的值为 6
), 则不能更改 key
(什么意思???), 否则共同编辑停止.
有待验证上面这句话, 不允许修改
key
是啥含义? 事实上, 更新key
就意味着新的文档. 在Vue
中可以使用绑定, 自动更新配置; 传统方法中, 可以使用docEditor
实例来通过方法来更新 配置 的数据.
还有一个需要验证, 关闭文档编辑器怎么实现? 已验证, 关闭浏览器就会触发保存 (
status
为2
).
一些结论
- 当用户采用同一个
key
进入 文档编辑器 时, 不会向本地后端发起文件请求, 而是使用ws
信道直接获取文件. - 事实上, 进入 文档编辑器 后, 文档编辑服务 会缓存所请求的文档, 但凡再次请求该文件 (用
key
标识), 都不会向本地服务发起请求. 文档编辑器 的配置中,key
是主导,url
只是在需要时, 用于请求的属性.