OnlyOffice document server installation and integrated use


0. Preface

Let’s start with a description from the official website: ONLYOFFICE Document is an open source office suite that includes text documents, spreadsheets, presentations and fillable form editors. It provides the following functions:

  • Create, edit, and view text documents, spreadsheets, presentations, and fillable forms
  • Collaborate on files in real time with other teammates.

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

Online effects such as:
word:
Insert image description here

excel:
Insert image description here

ppt:
Insert image description here

1. Installation

1. Install using 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

下载镜像

docker pull onlyoffice/documentserver

启动镜像,这里以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

2. Turn on the firewall

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

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

3.Configuration

启动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

4.Access test

http://IP:8088/

Insert image description here
可以通过自带的example应用进行测试:http://192.168.56.101:8088/example/

Insert image description here
When you see the screenshot above, the installation is complete.

2. Application integration

The above has installed OnlyOffice and experienced the online editing function through the example. However, if it needs to be formally used in our application system, corresponding program integration is also required. The integration is mainly divided into two parts: front-end and back-end interfaces.

1. Front-end integration (React)

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

(1).Install @onlyoffice/document-editor-react

yarn add @onlyoffice/document-editor-react

(2).Use ONLYOFFICE document React component

The following is a sample page file I wrote

index.less

html,
body {
    
    
    margin: 0;
    padding: 0;
}

.docx-editor-wrapper {
    
    
    height: 100vh;
    overflow: hidden;
}

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;

Important attribute description:
documentServerUrl: The address (IP and port) of the online editing document server
config.document.key: Defines the unique document identifier used by the service to identify the document. If a known key is sent, the document will be fetched from the cache. Each time you edit and save the document, the key must be regenerated. Document URLs can be used as keys, but they cannot use special characters and are limited to 128 symbols in length.
config.document.url: Define the absolute URL where the source document is stored for viewing or editing. The interface you write is used to obtain the source file and provide it to the online editing document server (见Java的实现部分).
config.editorConfig.callbackUrl:Specify the absolute address of the callback of the document storage service, that is, the background interface processor written by yourself, and use this interface to callback to save and process the edited file (见Java的实现部分).

For details on other parameters, please refer to this document: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;

2.Backend integration (Java)

(1) getFile interface

This interface is provided to the document editing server for document downloading.

(2) callback interface

This interface provides document processing after online saving.

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

The file is saved when status=2 is in the callback interface

(3) getFile interface and callback interface code

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;
    }
}

3. Other issues

1. The file version has changed and the page will be reloaded

If the file version has been changed, the page will be reloaded or the file version has been changed. the page will be reloaded. It may be because the key you used has been called back and will be considered changed.

Insert image description here
解决:更换新的key, that is, the following key parameter needs to be updated after 进行过callback处理后, and the same one cannot be used all the time.
Insert image description here

4. Source code download

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

Guess you like

Origin blog.csdn.net/jxlhljh/article/details/133700965