• OnlyOffice文档服务器安装及集成使用



    0、前言

    先摘一段官网的描述:ONLYOFFICE 文档 是一个开源办公套件,包括文本文档、电子表格、演示文稿和可填写表单的编辑器。 它提供以下功能:

    • 创建、编辑和查看文本文档、电子表格、演示文稿和可填写表单
    • 与其他队友实时协作处理文件。

    官网文档中文:
    https://api.onlyoffice.com/zh/editors/basic
    官网文档英文:
    https://api.onlyoffice.com/editors/basic

    在线效果如:
    word:
    在这里插入图片描述

    excel:
    在这里插入图片描述

    ppt:
    在这里插入图片描述

    一、安装

    1.使用docker安装

    创建安装目录

    mkdir /app/onlyoffice/DocumentServer/logs -p
    mkdir /app/onlyoffice/DocumentServer/data -p
    mkdir /app/onlyoffice/DocumentServer/lib -p
    mkdir /app/onlyoffice/DocumentServer/db -p
    
    • 1
    • 2
    • 3
    • 4

    下载镜像

    docker pull onlyoffice/documentserver
    
    • 1

    启动镜像,这里以8088端口对外进行服务,可自行修改

    docker run -i -t -d -p 8088:80 --restart=always \
        -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice  \
        -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data  \
        -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \
        -v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql -e JWT_SECRET=my_jwt_secret onlyoffice/documentserver
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.开启防火墙

    将上面的8088端口开放提供服务

    firewall-cmd --zone=public --add-port=8088/tcp --permanent
    firewall-cmd --reload
    
    • 1
    • 2

    3.配置

    启动docker后要过一小段时间,通过docker ps 查看已经运行的dockerId,复制出来后,执行下面的两条命令:

    sudo docker exec {onlyOffice Docker ID}  sudo supervisorctl start ds:example
    sudo docker exec {onlyOffice Docker ID} sudo sed 's,autostart=false,autostart=true,' -i /etc/supervisor/conf.d/ds-example.conf
    
    示例如:
    sudo docker exec a6caa73db3f3 sudo supervisorctl start ds:example
    sudo docker exec a6caa73db3f3 sudo sed 's,autostart=false,autostart=true,' -i /etc/supervisor/conf.d/ds-example.conf
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.访问测试

    http://IP:8088/
    
    • 1

    在这里插入图片描述
    可以通过自带的example应用进行测试:http://192.168.56.101:8088/example/

    在这里插入图片描述
    看到以上截图,即安装完成了。

    二、应用集成

    以上安装好OnlyOffice并通过example进行体验在线编辑功能,但如果需要在我们的应用系统中正式使用,还需要进行相应的程序集成,集成主要分前端和后台接口两部分。

    1.前端集成(React)

    参考文档:
    https://api.onlyoffice.com/zh/editors/react

    (1).安装@onlyoffice/document-editor-react

    yarn add @onlyoffice/document-editor-react
    
    • 1

    (2).使用 ONLYOFFICE 文档 React 组件

    以下为我写的页面样例文件

    index.less

    html,
    body {
        margin: 0;
        padding: 0;
    }
    
    .docx-editor-wrapper {
        height: 100vh;
        overflow: hidden;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    OnlyOfficeEditor组件代码:

    import React from 'react';
    import { DocumentEditor } from "@onlyoffice/document-editor-react";
    import './index.less';
    
    const OnlyOfficeEditor = () => {
    
        const onDocumentReady = (event) => {
            // 请输入函数体代码
            console.log("Document is loaded", event);
        };
    
        return (
            <div className='docx-editor-wrapper'>
    
                <DocumentEditor
                    id="docxEditor"
                    documentServerUrl="http://192.168.56.101:8088"
                    config={{
                        "document": {
                            "fileType": "docx",
                            "key": "Khirz6zTPdf2dsaazx",
                            "title": "Example Document Title.docx",
                            "url": "http://192.168.56.1:8888/getFile",
                            "permissions": {
                                "comment": true,
                                "copy": true,
                                "download": true,
                                "edit": true,
                                "print": true,
                                "fillForms": true,
                                "modifyFilter": true,
                                "modifyContentControl": true,
                                "review": true,
                                "commentGroups": {}
                            }
                        },
                        "documentType": "word", 
                        "type": "mobile", //mobile或者desktop,移动端还是桌面端效果
                        "editorConfig": {
                            "mode": "edit",
                            "lang": "zh-CN",
                            "callbackUrl": "http://192.168.56.1:8888/callback",
                            "user": {
                                "id": "liu",
                                "name": "liu"
                            },
                        },
                    }}
                    events_onDocumentReady={onDocumentReady}
                />
            </div>
        );
    };
    export default OnlyOfficeEditor;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    重要属性说明:
    documentServerUrl: 在线编辑文档服务器的地址(IP和端口)
    config.document.key: 定义服务用来识别文档的唯一文档标识符。如果发送了已知key,则将从缓存中获取文档。 每次编辑和保存文档时,都必须重新生成key。 文档 url 可以用作 key,但不能使用特殊字符,长度限制为 128 个符号。
    config.document.url:定义存储查看或编辑的源文档的绝对URL,自己写的接口用于获取源始文件提供给在线编辑文档服务器(见Java的实现部分)。
    config.editorConfig.callbackUrl:指定文档存储服务回调的绝对地址,即自己写的后台接口处理器,通过此接口进行回调保存处理编辑后的文件(见Java的实现部分)。

    其他参数详细参考此文档说明:https://api.onlyoffice.com/zh/editors/config

    在App.js中引用OnlyOfficeEditor组件

    import React from 'react';
    import OnlyOfficeEditor from 'src/components/onlyOfficeEditor';
    
    const App = () => {
      return (
        <div className='app'>
          <OnlyOfficeEditor />
        </div>
      )
    };
    
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.后台集成(Java)

    (1) getFile接口

    通过此接口提供给文档编辑服务器进行文档下载。

    (2) callback接口

    通过此接口提供进行在线保存后的文档处理。

    官网参考:https://api.onlyoffice.com/zh/editors/callback

    在回调接口中status=2时进行文件的保存处理

    (3) getFile接口和callback接口代码

    OnlyOfficeController.java中包含上面的两个接口代码

    package cn.ljhua.onlyoffice.controller;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URISyntaxException;
    import java.net.URLEncoder;
    import java.util.Collections;
    
    import javax.servlet.http.HttpServletResponse;
    
    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.CrossOrigin;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import cn.ljhua.onlyoffice.utils.HttpsKitWithProxyAuth;
    import lombok.Getter;
    import lombok.Setter;
    
    /**
     * @author liujh
     */
    @RestController
    public class OnlyOfficeController {
    
        private static final String FILE_PATH = "D:/temp/1.docx"; //这里仅写死路径测试
    
        @CrossOrigin(origins = "*", methods = {RequestMethod.GET, RequestMethod.OPTIONS})
        @GetMapping("/getFile")
        public ResponseEntity<byte[]> getFile(HttpServletResponse response) throws IOException {
        	
            File file = new File(FILE_PATH);
            FileInputStream fileInputStream = null;
            InputStream fis = null;
            try {
            	fileInputStream = new FileInputStream(file);
                fis = new BufferedInputStream(fileInputStream);
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                // 替换为实际的文档名称
                headers.setContentDispositionFormData("attachment", URLEncoder.encode(file.getName(), "UTF-8"));
                return new ResponseEntity<>(buffer, headers, HttpStatus.OK);
            } catch (Exception e) {
                throw new RuntimeException("e -> ", e);
            } finally {
            	
            	try {
    				if(fis != null) fis.close();
    			} catch (Exception e) {
    				
    			}
            	
            	try {
    				if(fileInputStream != null) fileInputStream.close();
    			} catch (Exception e) {
    				
    			}
            	
            }
            
        }
    
        @CrossOrigin(origins = "*", methods = {RequestMethod.GET,RequestMethod.POST, RequestMethod.OPTIONS})
        @PostMapping("/callback")
        public ResponseEntity<Object> handleCallback(@RequestBody CallbackData callbackData) {
    
        	//状态监听
            //参见https://api.onlyoffice.com/editors/callback
            Integer status = callbackData.getStatus();
            switch (status) {
                case 1: {
                    //document is being edited  文档已经被编辑
                    break;
                }
                case 2: {
                    //document is ready for saving,文档已准备好保存
                	System.out.println("document is ready for saving");
                    String url = callbackData.getUrl();
                    try {
                        saveFile(url); //保存文件
                    } catch (Exception e) {
                        System.out.println("保存文件异常");
                    }
                    System.out.println("save success.");
                    break;
                }
                case 3: {
                    //document saving error has occurred,保存出错
                    break;
                }
                case 4: {
                    //document is closed with no changes,未保存退出
                    break;
                }
                case 6: {
                    //document is being edited, but the current document state is saved,编辑保存
                }
                case 7: {
                    //error has occurred while force saving the document. 强制保存文档出错
                }
                default: {
    
                }
            }
            
            // 返回响应
            return ResponseEntity.<Object>ok(Collections.singletonMap("error", 0));
    
        }
    
        public void saveFile(String downloadUrl) throws URISyntaxException, IOException {
        	
            HttpsKitWithProxyAuth.downloadFile(downloadUrl, FILE_PATH);
            
        }
    
        @Setter
        @Getter
        public static class CallbackData  {
            /**
             * 用户与文档的交互状态。0:用户断开与文档共同编辑的连接;1:新用户连接到文档共同编辑;2:用户单击强制保存按钮
             */
    //        @IsArray()
    //        actions?:IActions[] =null;
    
            /**
             * 字段已在 4.2 后版本废弃,请使用 history 代替
             */
            Object changeshistory;
    
            /**
             * 文档变更的历史记录,仅当 status 等于 2 或者 3 时该字段才有值。其中的 serverVersion 字段也是 refreshHistory 方法的入参
             */
            Object history;
    
            /**
             * 文档编辑的元数据信息,用来跟踪显示文档更改记录,仅当 status 等于 2 或者 2 时该字段才有值。该字段也是 setHistoryData(显示与特定文档版本对应的更改,类似 Git 历史记录)方法的入参
             */
            String changesurl;
    
            /**
             * url 字段下载的文档扩展名,文件类型默认为 OOXML 格式,如果启用了 assemblyFormatAsOrigin(https://api.onlyoffice.com/editors/save#assemblyFormatAsOrigin) 服务器设置则文件以原始格式保存
             */
            String filetype;
    
            /**
             * 文档强制保存类型。0:对命令服务(https://api.onlyoffice.com/editors/command/forcesave)执行强制保存;1:每次保存完成时都会执行强制保存请求,仅设置 forcesave 等于 true 时生效;2:强制保存请求由计时器使用服务器中的设置执行。该字段仅 status 等于 7 或者 7 时才有值
             */
            Integer forcesavetype;
    
            /**
             * 文档标识符,类似 id,在 Onlyoffice 服务内部唯一
             */
            String key;
    
            /**
             * 文档状态。1:文档编辑中;2:文档已准备好保存;3:文档保存出错;4:文档没有变化无需保存;6:正在编辑文档,但保存了当前文档状态;7:强制保存文档出错
             */
            Integer status;
    
            /**
             * 已编辑文档的链接,可以通过它下载到最新的文档,仅当 status 等于 2、3、6 或 7 时该字段才有值
             */
            String url;
    
            /**
             * 自定义参数,对应指令服务的 userdata 字段
             */
            Object userdata;
    
            /**
             * 打开文档进行编辑的用户标识列表,当文档被修改时,该字段将返回最后编辑文档的用户标识符,当 status 字段等于 2 或者 6 时有值
             */
            String[] users;
    
            /**
             * 最近保存时间
             */
            String lastsave;
    
            /**
             * 加密令牌
             */
            String token;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198

    三、其他问题

    1. 该文件版本已变,该页面将被重新加载

    出现该文件版本已变,该页面将被重新加载或者the file version has been changed. the page will be reload.可能是因为你使用的key进行了回调处理,会被认为改变,

    在这里插入图片描述
    解决:更换新的key,即以下面的key参数进行过callback处理后后就需要更新了,不能一直用同一个。
    在这里插入图片描述

    四、源码下载

    github: https://github.com/jxlhljh/onlyOfficeTest.git
    gitee: https://gitee.com/jxlhljh/onlyOfficeTest.git

  • 相关阅读:
    phpstudy 安装 flarum论坛
    【C++】内存管理到用new申请堆内存
    华为云14天鸿蒙设备开发-Day9网络应用开发
    下班前几分钟,Express 快速入门
    Android Java JVM常见问答分析与总结
    数据库的优化的一些策略
    【空间&单细胞组学】第1期:单细胞结合空间转录组研究PDAC肿瘤微环境
    网络安全管理与运维服务
    windows故障转移集群磁盘扩容
    java计算机毕业设计石家庄市居家养老服务平台源码+数据库+系统+lw文档+mybatis+运行部署
  • 原文地址:https://blog.csdn.net/jxlhljh/article/details/133700965