帮助中心/最新通知

质量为本、客户为根、勇于拼搏、务实创新

< 返回文章列表

【运维相关】将 LibreOffice Online 集成到 Web 系统:基于 WOPI 的全流程指南

发表时间:2025-01-16 01:32:56 小编:油条

? 为什么选择 LibreOffice Online + WOPI?

  • LibreOffice Online 是一款开源在线文档套件,支持 .docx.xlsx.pptx 等格式编辑。
  • WOPI 协议(Web Application Open Platform Interface) 是一套由微软提出的标准接口,适用于文档服务与编辑器的对接。
  • 两者结合可让您的 Web 应用拥有媲美 Office Online 的在线编辑体验,无须额外客户端。

?️ 前提条件

类别

要求

技术能力

熟悉 Web 开发、REST API、Docker 基础操作

环境配置

可使用 Docker 的服务器(推荐 Linux 环境)

可用端口

开放 9980(LibreOffice Online) 和 8080(WOPI 服务)端口


?️ 项目结构预览(Mermaid)


? 第 1 步:部署 LibreOffice Online 服务

我们使用由 Collabora 发布的官方 Docker 镜像:

1.1 创建 docker-compose.yaml
代码语言:javascript
AI代码解释
复制
version: "3.6"
services:
  libreoffice-app:
    image: collabora/code:6.4.8.4
    container_name: libreoffice-app
    ports:
      - "9980:9980"
    environment:
      - username=admin
      - password=adminadmin
    restart: always
1.2 启动服务
代码语言:javascript
AI代码解释
复制
docker-compose up -d
1.3 验证服务状态

浏览器访问以下地址确认运行状态:

端点

描述

https://localhost:9980/hosting/discovery

发现端点(返回 XML 文件,描述支持的 MIME 类型)

https://localhost:9980/hosting/capabilities

能力端点(返回 JSON)

https://localhost:9980/loleaflet/dist/admin/admin.html

管理界面(使用 admin 密码登录)


? 第 2 步:实现 WOPI Host 服务(Python Flask 示例)

WOPI Host 是您的业务服务,负责:

  • 提供文件元信息
  • 提供文档内容读写能力
  • 验证访问者身份
2.1 三大核心端点说明

接口

方法

功能

/wopi/files/<filename>

GET

返回文件基本信息

/wopi/files/<filename>/contents

GET

读取文件内容

/wopi/files/<filename>/contents

POST / PUT

保存文件内容

2.2 最小实现代码(适合开发测试)
代码语言:javascript
AI代码解释
复制
from flask import Flask, jsonify, request, send_file
import os

app = Flask(__name__)
file_dir = '/tmp/'  # 替换为实际存储路径

@app.route('/wopi/files/<filename>', methods=['GET'])
def check_file_info(filename):
    path = os.path.join(file_dir, filename)
    if not os.path.exists(path):
        return jsonify({"error": "File not found"}), 404
    return jsonify({
        "BaseFileName": filename,
        "Size": os.path.getsize(path),
        "OwnerId": "user1",
        "UserId": "user1",
        "UserCanWrite": True,
        "ReadOnly": False
    })

@app.route('/wopi/files/<filename>/contents', methods=['GET'])
def get_file(filename):
    return send_file(os.path.join(file_dir, filename), as_attachment=True)

@app.route('/wopi/files/<filename>/contents', methods=['POST', 'PUT'])
def put_file(filename):
    with open(os.path.join(file_dir, filename), 'wb') as f:
        f.write(request.data)
    return jsonify({"status": "saved"})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

? 第 3 步:同时启动 WOPI 与 LibreOffice Online

推荐使用统一 docker-compose.yaml
代码语言:javascript
AI代码解释
复制
version: "3.6"
services:
  wopi-app:
    image: mywopi-service  # 请替换为您构建的 WOPI 镜像
    ports:
      - "8080:8080"

  libreoffice-app:
    image: collabora/code:6.4.8.4
    container_name: libreoffice-app
    ports:
      - "9980:9980"
    environment:
      - username=admin
      - password=adminadmin
    restart: always

✅ 建议通过 Dockerfile 构建 mywopi-service 镜像,并将 WOPI 服务打包进去。


? 第 4 步:在前端页面嵌入编辑器

4.1 使用 iframe 加载 LibreOffice 编辑器:
代码语言:javascript
AI代码解释
复制
<iframe
  src="https://localhost:9980/loleaflet/1430151/loleaflet.html?WOPISrc=http://wopi-app:8080/wopi/files/test.odt&access_token=test"
  width="100%" height="800px">
</iframe>
4.2 替代方案:表单方式加载
代码语言:javascript
AI代码解释
复制
<form action="https://localhost:9980/loleaflet/1430151/loleaflet.html" method="post">
  <input name="WOPISrc" value="http://wopi-app:8080/wopi/files/test.odt" />
  <input name="access_token" value="test" />
  <input type="submit" value="打开文档" />
</form>

? 第 5 步:访问控制和安全性建议

  • 始终使用 access_token 参数进行鉴权
  • 推荐使用 JWT 或时间戳签名机制,防止 URL 被滥用
  • 所有 WOPI 请求都必须验证令牌有效性
示例 JWT 用法:
代码语言:javascript
AI代码解释
复制
<iframe
  src="https://localhost:9980/loleaflet/1430151/loleaflet.html?WOPISrc=http://wopi-app:8080/wopi/files/test.odt&access_token=your_jwt_token"
  width="100%" height="800px">
</iframe>

⚙️ 第 6 步:配置 LibreOffice Online 行为(loolwsd.xml)

您可以进入容器内部修改配置:

代码语言:javascript
AI代码解释
复制
docker exec -it libreoffice-app bash
nano /etc/loolwsd/loolwsd.xml
可调整项包括:
  • 日志级别 <logging>
  • 语言包支持 <languages>
  • 允许的域名白名单 <host> / <allow> 节点
  • 并发会话数上限

? 第 7 步:使用 postMessage 与编辑器交互

LibreOffice Online 支持基于 window.postMessage 的交互 API

示例:保存文档
代码语言:javascript
AI代码解释
复制
function post(message) {
  window.parent.postMessage(JSON.stringify(message), '*');
}

post({
  MessageId: "Action_Save",
  Values: {
    DontTerminateEdit: true,
    DontSaveIfUnmodified: false,
    Notify: true
  }
});
可实现功能包括:
  • 主动保存
  • 通知前端文档是否已修改
  • 监听事件(如加载完成、退出等)

实用小工具

App Store 截图生成器应用图标生成器在线图片压缩Chrome插件-强制开启复制-护眼模式-网页乱码设置编码 乖猫记账,AI智能分类的聊天记账。


联系我们
返回顶部