Springboot集成OnlyOffice

一、OnlyOffice 是什么?为什么选择它?​

ONLYOFFICE 是一款开源免费的全功能办公套件,核心优势在于文档在线编辑、实时协同与灵活集成能力,完美适配企业级私有化部署需求。它支持 Word、Excel、PPT、PDF 等主流格式的查看与编辑,还提供 AI 辅助编辑(文本生成、翻译、语法检查)、跨平台协作(内置聊天、音视频通话)、三级加密(静态 / 传输 / 端到端)等进阶功能,且拥有完善的中文文档和活跃社区。​

相比 OpenOffice、Office Online,OnlyOffice 的核心竞争力体现在:​

  1. 开源可定制:社区版基于 AGPL 3.0 协议,支持二次开发(如突破 20 人协同限制);
  1. 集成友好:提供全面的 REST API,支持与 40+ 平台无缝对接(Nextcloud、Moodle 等);
  1. 协同高效:支持字符级实时协作,多人编辑无冲突,自带修订记录与评论功能;
  1. 生态完善:覆盖桌面端(Windows/Linux/macOS)、移动端(iOS/Android)与网页端,满足全场景需求。

适合场景:企业内部文档协作平台、SaaS 产品嵌入在线编辑功能、私有化办公系统搭建等。​

二、Docker 快速部署 OnlyOffice Docs 服务​

Docker 是部署 OnlyOffice 最便捷的方式,无需复杂依赖配置,一键启动完整服务(含文档服务器、数据库)。​

前提条件​

  • 已安装 Docker 与 Docker Compose(推荐 Docker 版本 ≥ 20.10);
  • 服务器内存 ≥ 2GB(官方建议,否则编辑时可能卡顿);
  • 开放 80 端口(或自定义端口),确保网络可访问。

部署步骤​

  1. 拉取官方镜像​

OnlyOffice 文档服务器的官方镜像已包含核心依赖,直接拉取即可:​

拉取最新版 OnlyOffice Docs 镜像​

docker pull onlyoffice/documentserver​

注意:若 Docker Hub 访问受限,可通过国内镜像源同步(如阿里云镜像仓库),避免自行打包镜像(易出现兼容性问题)。​

简化版(无需 MySQL,使用内置 SQLite):​

docker run --name onlyoffice-docs -d -p 8088:80 --restart=always onlyoffice/documentserver​

适合测试环境,生产环境建议用 MySQL 保证数据可靠性。​

onlyoffice默认开启token,如果不需要token可以加-e JWT_ENABLED=false

  1. 验证部署成功​

容器启动后(约 1-2 分钟),访问 http://服务器IP:8088,若看到 OnlyOffice 欢迎页面,则部署成功:​

常见问题解决​

  1. 权限不足:若容器启动失败,添加 --privileged=true 参数赋予权限;
  1. 端口占用:修改 -p 映射端口(如 8089:80),避免与其他服务冲突;
  1. 中文字体缺失:进入容器复制本地中文字体(如 SimHei.ttf)到 /var/www/onlyoffice/documentserver/core-fonts,执行 documentserver-generate-allfonts.sh 刷新缓存。

SpringBoot的集成

在动手写代码前,我们需要先理清集成的核心逻辑,准备好所需环境,避免后续踩坑。

核心原理:OnlyOffice 与 Spring Boot 如何交互?

OnlyOffice 的集成本质是 "前端渲染 + 后端通信" 的组合:

  • 前端:通过 OnlyOffice 提供的 JavaScript API,在页面中嵌入文档编辑器组件,负责文档的可视化编辑、格式渲染;
  • 后端(Spring Boot) :作为 "中间桥梁",承担三个关键角色:
    1. 提供文档文件的存储(本地 / 云存储)与访问接口(如下载文档的 URL);
    2. 处理 OnlyOffice 的回调通知(如文档编辑完成后,接收 OnlyOffice 返回的编辑结果,更新本地文件)。

简单来说:用户在前端编辑文档时,操作会实时同步到 OnlyOffice 服务端;编辑完成后,OnlyOffice 会通知 Spring Boot 后端,后端再从 OnlyOffice 获取最新文档并保存 ------ 整个流程需保证 "文件地址可访问""接口权限合法""回调处理可靠"。

步骤 1:配置 OnlyOffice 服务地址

application.properties 中配置 OnlyOffice 服务地址和回调接口地址:

复制代码
# OnlyOffice Document Server 地址(前端加载编辑器用)
onlyoffice.server.url=http://onlyoffice-ip:8080
# 后端回调接口地址(OnlyOffice 保存文档时调用)
onlyoffice.callback.url=http://your-springboot-ip:8081/api/onlyoffice/callback
# 文档存储路径(本地存储示例)
doc.storage.path=/app/documents/

步骤 2:后端核心接口实现

2.1 文档配置接口(给前端返回编辑器参数)

前端加载 OnlyOffice 编辑器时,需要从后端获取文档的配置信息(如文件地址、权限、回调地址等)。

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/onlyoffice")
public class OnlyOfficeController {

    @Value("${onlyoffice.server.url}")
    private String onlyofficeServerUrl;

    @Value("${onlyoffice.callback.url}")
    private String callbackUrl;

    @Value("${doc.storage.path}")
    private String docStoragePath;

    // 文档配置接口:前端请求此接口获取编辑器参数
    @GetMapping("/config")
    public Map<String, Object> getDocConfig(@RequestParam String fileName) throws Exception {
        // 1. 构建文档访问地址(后端提供的文档下载地址)
        String docUrl = "http://your-springboot-ip:8081/api/doc/download?fileName=" + fileName;

        // 2. 配置 OnlyOffice 编辑器参数
        Map<String, Object> config = new HashMap<>();
        config.put("document", Map.of(
                "fileType", fileName.split("\\.")[1], // 文档类型(如 docx、xlsx)
                "key", fileName, // 文档唯一标识(建议用文件MD5或UUID)
                "title", fileName,
                "url", docUrl // 文档下载地址(OnlyOffice 会从这里拉取文件)
        ));

        // 3. 配置编辑器权限(是否可编辑)
        config.put("editorConfig", Map.of(
                "callbackUrl", callbackUrl, // 保存回调地址
                "user", Map.of("id", "1", "name", "张三"), // 当前用户信息
                "mode", "edit" // 模式:edit(编辑)/ view(查看)
        ));

        // 4. 配置 OnlyOffice 服务地址
        config.put("documentServerUrl", onlyofficeServerUrl);

        return config;
    }
}
2.2 文档下载接口(OnlyOffice 拉取文件用)

OnlyOffice 编辑器需要从后端下载文档进行编辑,因此需要提供一个下载接口:

java 复制代码
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;

@RestController
@RequestMapping("/api/doc")
public class DocController {

    @Value("${doc.storage.path}")
    private String docStoragePath;

    // 文档下载接口:OnlyOffice 从这里拉取文件
    @GetMapping("/download")
    public ResponseEntity<byte[]> downloadDoc(@RequestParam String fileName) throws Exception {
        File docFile = new File(docStoragePath + fileName);
        if (!docFile.exists()) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        // 设置响应头(指定文件类型)
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileName);

        return new ResponseEntity<>(FileUtils.readFileToByteArray(docFile), headers, HttpStatus.OK);
    }
}
2.3 回调接口(OnlyOffice 保存文档时调用)

当用户编辑完成并点击保存后,OnlyOffice 会将编辑后的文档通过回调接口发送到后端,后端需要接收并保存文件。

java 复制代码
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.net.URL;

@RestController
@RequestMapping("/api/onlyoffice")
public class OnlyOfficeCallbackController {

    @Value("${doc.storage.path}")
    private String docStoragePath;

    private final ObjectMapper objectMapper = new ObjectMapper();

    // 回调接口:OnlyOffice 保存文档时调用
    @PostMapping("/callback")
    public ResponseEntity<String> callback(@RequestBody JsonNode body) throws Exception {
        // 1. 解析回调参数
        String status = body.get("status").asText(); // 状态:2 - 已保存,3 - 保存并关闭
        if (!"2".equals(status) && !"3".equals(status)) return ResponseEntity.ok("{\"error\":0}");
        String url = body.get("url").asText(); // 编辑后文档的临时URL(OnlyOffice 提供)
        String fileName = body.get("key").asText(); // 文档唯一标识(与配置中的key一致)

        // 2. 状态为2或3时,下载并保存文档
        if ("2".equals(status) || "3".equals(status)) {
            // 从 OnlyOffice 提供的临时URL下载编辑后的文件
            File editedFile = new File(docStoragePath + fileName);
            FileUtils.copyURLToFile(new URL(url), editedFile);
        }

        // 3. 必须返回 {"error":0},否则 OnlyOffice 会认为回调失败并重复调用
        return ResponseEntity.ok("{\"error\":0}");
    }
}

步骤 3:前端页面集成 OnlyOffice 编辑器

前端需要引入 OnlyOffice 的 JS 脚本,并通过后端返回的配置信息初始化编辑器。

示例(HTML + JavaScript):

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>OnlyOffice 编辑示例</title>
    <!-- 引入 OnlyOffice 编辑器脚本(地址为部署的 Document Server) -->
    <script src="http://onlyoffice-ip:8080/web-apps/apps/api/documents/api.js"></script>
</head>
<body>
    <!-- 编辑器容器 -->
    <div id="onlyofficeEditor" style="width: 100%; height: 800px;"></div>

    <script>
        // 从后端获取文档配置
        fetch('http://your-springboot-ip:8081/api/onlyoffice/config?fileName=test.docx')
            .then(response => response.json())
            .then(config => {
                // 初始化 OnlyOffice 编辑器
                new DocsAPI.DocEditor("onlyofficeEditor", config);
            });
    </script>
</body>
</html>
相关推荐
晨非辰26 分钟前
【数据结构】排序详解:从快速排序分区逻辑,到携手冒泡排序的算法效率深度评测
运维·数据结构·c++·人工智能·后端·深度学习·排序算法
5pace28 分钟前
【SSM|第一篇】MyBatisPlus
java·spring boot·后端·mybatis
JosieBook42 分钟前
【SpringBoot】37 核心功能 - 高级特性- Spring Boot 中的 自定义 Starter 完整教程
java·spring boot·后端
百***06941 小时前
Skywalking介绍,Skywalking 9.4 安装,SpringBoot集成Skywalking
spring boot·后端·skywalking
小二·1 小时前
Elasticsearch 面试题精编(26题|含答案|分类整理)
java·大数据·elasticsearch
BD_Marathon1 小时前
在 Linux 环境中配置 Eclipse 以开发 Hadoop 应用
java·hadoop·eclipse
百***37481 小时前
Spring Boot 中 RabbitMQ 的使用
spring boot·rabbitmq·java-rabbitmq
IT_陈寒1 小时前
Python 3.12新特性实战:5个让你的代码效率翻倍的隐藏技巧!
前端·人工智能·后端
草莓熊Lotso1 小时前
C++ 二叉搜索树(BST)完全指南:从概念原理、核心操作到底层实现
java·运维·开发语言·c++·人工智能·经验分享·c++进阶