目 录CONTENT

文章目录

onlyoffice整合springboot+vue实现文档在线编辑保存

成培培
2025-08-26 / 0 评论 / 0 点赞 / 29 阅读 / 0 字

项目上需要用到在线word、excel文档编辑功能,通过游览器在线打开一个远程的word文档编辑保存,这里记录下整合思路。

onlyoffice简介

ONLYOFFICE 是一款开源的办公套件,提供了一系列在线文档编辑和协作工具,适用于团队和个人使用。它支持文档、表格、演示文稿等格式的创建、编辑和共享,类似于 Google Docs、Microsoft Office 365 等办公软件。
官方文档:https://api.onlyoffice.com/zh-CN/docs/docs-api/get-started/basic-concepts/

onlyoffice部署安装

使用onlyoffice我们需要先部署一套文档服务onlyoffice/documentserver,它是onlyoffice办公套件的核心组件之一,主要用于处理文档的在线编辑和协作功能。它是 ONLYOFFICE 的文档处理服务器,专门负责处理用户上传的文档,支持文档、表格和演示文稿等格式的在线编辑。
这是部署方式选择docker,比较简单一条命令即可:

docker run -i -t -d -p 9097:80 --privileged=true \
--name docserver --restart=always -e TZ=Asia/Shanghai \
-e ALLOW_PRIVATE_IP_ADDRESS=true -e JWT_ENABLED=false \
onlyoffice/documentserver

其中参数JWT_ENABLED=false是关闭签名校验,内网使用的话关掉整合起来会方便些,参数ALLOW_PRIVATE_IP_ADDRESS是允许内网IP回调,documentserver本身回调我们的业务系统,如果是内网的IP需要设置这个参数,否则默认回调不到,这里我被坑了半天,一直以为是docker网络配置问题。

VUE整合

这里可以参考官方文档的这一页:https://api.onlyoffice.com/zh-CN/docs/docs-api/get-started/frontend-frameworks/vue/
参考文档按照以下命令可以创建一个vue使用onlyoffice的范例:

# 创建一个名为 _onlyoffice-vue-demo_ 的 Vue.js 3.x 项目
npm create vue@3
# 进入新创建的目录
cd onlyoffice-vue-demo
# 安装 ONLYOFFICE 文档 Vue.js 组件,并使用 _--save_ 将其保存到 _package.json_ 文件中
npm  install  --save @onlyoffice/document-editor-vue

打开工程将项目中的 ./src/App.vue 文件,并将其内容替换为以下代码:

<template>
    <DocumentEditor 
        id="docEditor" 
        documentServerUrl="http://192.168.3.96:9097/"
        :config="config"
        :events_onDocumentReady="onDocumentReady"
        :onLoadComponentError="onLoadComponentError"
        height="900px"
    /> 
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { DocumentEditor } from "@onlyoffice/document-editor-vue";

export default defineComponent({
    name: 'ExampleComponent',
    components: {
        DocumentEditor
    },
    data() {
        return {
            config: {
                document: {
                    fileType: "docx",
                    key: "Khirz6zTPdfd7",
                    title: "这是一个测试文档",
                    url: "https://home.chengpei.top:8443/root/491f72dd4faa38a214dd8bd1ddb552a9.docx"
                },
                documentType: "word",
                editorConfig: {
                    callbackUrl: "http://192.168.3.213:8080/url-to-callback"
                },
                // token: "xxxxxxxxxxxx"
            }
        }
    },
    methods: {
        onDocumentReady() {
            console.log("Document is loaded");
        },
        onLoadComponentError (errorCode, errorDescription) {
            switch(errorCode) {
                case -1: // Unknown error loading component
                    console.log(errorDescription);
                    break;

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

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

这里需要特别注意的几个参数如下:
documentServerUrl: documentserver服务的URL,也就是上面docker搭建的服务
config: 这是当前要编辑的文档的描述配置,包含文档信息(document)、文档类型(documentType)、编辑配置(editorConfig)、签名(token)等
callbackUrl: 保存回调地址,当发生编辑器打开、关闭、强制保存等操作时,会回调我们的业务系统执行对应操作,比如保存文件之类的,这是一个我们业务系统必须实现的接口
token: 签名如果在部署documentserver时配置了JWT_ENABLED=true则签名是必须传的,签名的计算逻辑参考官方文档:https://api.onlyoffice.com/zh-CN/docs/docs-api/additional-api/signature/

其中config参数按理说不应该前端这么写死的,config中的参数全都是当前这个待编辑文件的相关信息,应该直接又后端业务系统返回,比如:页面上展示了一些可编辑文件列表,选择某个文件点击编辑时,后端根据选择的文件组装config信息,包含文件的ID(key)、文件类型(fileType)、文件下载地址(url)等,前端拿到config直接传给DocumentEditor组建打开一个onlyoffice的文件编辑窗口即可编辑了,文件编辑过程中是自动保存的,文件有变动马上会触发保存,但是这时文件并不是真的保存了,等到窗口关闭时,或者前端调用了强制保存时,documentserver会回调上面配置的callbackUrl接口,传入以下请求体:

{
    "actions": [
        {
            "type": "DISCONNECTED",
            "userid": "uid-1756171298433"
        }
    ],
    "changesurl": "http://192.168.3.96:9097/cache/files/data/111ac2d8a0815d729fa9_702/changes.zip/changes.zip?md5=Ojhah6-hu1pd_VOr8-uJrA&expires=1756197053&shardkey=undefined&filename=changes.zip",
    "filetype": "docx",
    "history": {
        "serverVersion": "9.0.4",
        "changes": [
            {
                "documentSha256": "fcffb173437380e77bd16661b2a1be0e71c40bb318184acd64da061b3621c186",
                "created": "2025-08-26 08:15:42",
                "user": {
                    "id": "uid-1756171298433",
                    "name": "Anonymous"
                }
            }
        ]
    },
    "key": "111ac2d8a0815d729fa9",
    "status": "SAVE",
    "url": "http://192.168.3.96:9097/cache/files/data/111ac2d8a0815d729fa9_702/output.docx/output.docx?md5=raC8B92ncNB4wcvrRz1CkQ&expires=1756197053&shardkey=undefined&filename=output.docx",
    "users": [
        "uid-1756171298433"
    ]
}

其中url为修改后的文件,业务系统收到该回调后可以保存该文件,实现业务上的文件保存功能。
前端也可以手动调用接口触发回调强制保存,详细参考官方文档命令服务 - forcesave

后端回调接口实现

这里后端使用springboot,实现以下这个接口即可:

@PostMapping(value = "/url-to-callback")
public String callback(@RequestBody final Callback body) {
    log.info("======== url-to-callback ========");
    try {
        String bodyString = JSONUtil.toJsonStr(body);
        if (bodyString.isEmpty()) {  // if the request body is empty, an error occurs
            throw new RuntimeException("{\"error\":1,\"message\":\"Request payload is empty\"}");
        }
        log.info(bodyString);
        // TODO 判断当前是什么操作什么状态,根据情况保存url里的文件
    } catch (Exception e) {
        String message = e.getMessage();
        if (!message.contains("\"error\":1")) {
            log.error("callback Exception", e);
        }
        return message;
    }
    return "{\"error\":\"0\"}";
}

Callback是onlyoffice SDK依赖里的一个类,封装了回调的参数依赖如下:

<dependency>
    <groupId>com.onlyoffice</groupId>
    <artifactId>docs-integration-sdk</artifactId>
    <version>1.4.0</version>
</dependency>

你也可以在回调地址后面拼上?param=xxx传一些自定义的参数,通过@RequestParam拿到

0

评论区