91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OnlyOffice基礎實踐

發布時間:2020-06-27 16:19:52 來源:網絡 閱讀:33457 作者:mybabe0312 欄目:開發技術

一:概述

onlyoffice是做什么用的在這里就不做解釋了,能看到這篇博客的我相信都是了解的,本文主要講解onlyoffice在使用過程中要注意的問題。

使用環境:window10 + VMware Workstation Pro14 + CentOS-7-x86_64-Minimal + Docker 18.03.1-ce + onlyoffice

onlyoffice官網:https://www.onlyoffice.com/
onlyoffice API: https://api.onlyoffice.com/editors/basic

onlyoffice API要著重看下,里面闡述了onlyoffice的運行原理,同時里面有基于多種語言的樣例代碼,基本理解onlyoffice的運行原理后再結合樣例代碼驗證必能事半功倍。在這首先闡述下API中設計到的幾個概念:
1,document manager : 文檔管理器,等同于一個界面中的文件列表,該列表就是文檔管理器【我們自己編寫,不一定需要】。
2,document storage service :文檔存儲服務,即管理文檔存放的模塊,很多時候就是我們上傳文件然后將其保存在服務器上,網上也有使用nextcloud作為存儲的【我們自己編寫或使用存儲文件的軟件】。
3,document editor : 文檔編輯器,就是文檔編輯窗口【onlyoffice提供的前端頁面插件】
4,document editing service : 文檔編輯服務,從文檔存儲服務獲取要編輯的文檔,轉換成Office OpenXML格式后傳給文檔編輯器,編輯期間文檔編輯器與文檔編輯服務長期交互【onlyoffice提供的后臺服務】

二:實踐(基于樣例代碼)
首先從官網下載基于java開發的樣例代碼“Java Example.zip”,該代碼是使用maven構建的webapp,在webapp目錄下有兩個文件“index.jsp”和"editor.jsp"; 同時在resources目錄下有個setting.properties配置文件,這三個文件是我們首先要著重看的地方。

如果index.jsp能順利運行起來,那界面應該是這樣的:
OnlyOffice基礎實踐

首先我們可以點擊“Choose file”按鈕上傳一個要編輯的文件,這時會調用 controllers.IndexServlet中的doPost方法。其處理方法為:

protected void proce***equest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String action = request.getParameter("type");
        if(action == null)  {
            request.getRequestDispatcher("index.jsp").forward(request, response);
            return;
        }
        DocumentManager.Init(request, response);
        PrintWriter writer = response.getWriter();
        switch (action.toLowerCase())
        {
            case "upload":
                Upload(request, response, writer);
                break;
            case "convert":
                Convert(request, response, writer);
                break;
            case "track":
                Track(request, response, writer);
                break;
        }
    }
private static void Upload(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
    {
        response.setContentType("text/plain");
        try
        {
            Part httpPostedFile = request.getPart("file");
            String fileName = "";
            for (String content : httpPostedFile.getHeader("content-disposition").split(";"))
            {
                if (content.trim().startsWith("filename"))
                {
                    fileName = content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
                }
            }
            long curSize = httpPostedFile.getSize();
            if (DocumentManager.GetMaxFileSize() < curSize || curSize <= 0)
            {
                writer.write("{ \"error\": \"File size is incorrect\"}");
                return;
            }
            String curExt = FileUtility.GetFileExtension(fileName);
            if (!DocumentManager.GetFileExts().contains(curExt))
            {
                writer.write("{ \"error\": \"File type is not supported\"}");
                return;
            }
            InputStream fileStream = httpPostedFile.getInputStream();
            fileName = DocumentManager.GetCorrectName(fileName);
                        //文件保存路徑
            String fileStoragePath = DocumentManager.StoragePath(fileName, null);

            File file = new File(fileStoragePath);
            try (FileOutputStream out = new FileOutputStream(file))
            {
                int read;
                final byte[] bytes = new byte[1024];
                while ((read = fileStream.read(bytes)) != -1)
                {
                    out.write(bytes, 0, read);
                }
                out.flush();
            }
            writer.write("{ \"filename\": \"" + fileName + "\"}");
        }
        catch (IOException | ServletException e)
        {
            writer.write("{ \"error\": \"" + e.getMessage() + "\"}");
        }
    }

深入的不在闡述,經過幾番周折后,最終是將文件保存在硬盤上。這個上傳操作在實際應用onlyoffice的項目中也應該會有,實現方法和存放的路徑根據實際調整即可。

上傳過程界面如下:
OnlyOffice基礎實踐

當點擊“Edit”按鈕后,將會通過EditorServlet跳轉到“editor.jsp頁面”,并將需要的參數傳遞過去。其中關鍵的代碼為

docEditor = new DocsAPI.DocEditor("iframeEditor",
                {
                    width: "100%",
                    height: "100%",
                    type: "${type}",
                    documentType: "<%= Model.GetDocumentType() %>",
                    document: {
                        title: fileName,
                        url: "<%= Model.GetFileUri() %>",
                        fileType: fileType,
                        key: "<%= Model.GetKey() %>",
                        info: {
                            author: "Me",
                            created: "<%= new SimpleDateFormat("MM/dd/yyyy").format(new Date()) %>",
                        },
                        permissions: {
                            edit: <%= Boolean.toString(DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(Model.GetFileName()))).toLowerCase() %>,
                            download: true,
                        }
                    },
                    editorConfig: {
                        mode: "<%= DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(Model.GetFileName())) && !"view".equals(request.getAttribute("mode")) ? "edit" : "view" %>",
                        lang: "en",
                        callbackUrl: "<%= Model.GetCallbackUrl() %>",
                        user: {
                            id: "<%= Model.CurUserHostAddress() %>",
                            name: "John Smith",
                        },
                        embedded: {
                            saveUrl: "<%= Model.GetFileUri() %>",
                            embedUrl: "<%= Model.GetFileUri() %>",
                            shareUrl: "<%= Model.GetFileUri() %>",
                            toolbarDocked: "top",
                        },
                        customization: {
                            about: true,
                            feedback: true,
                            goback: {
                                url: "<%= Model.GetServerUrl() %>/IndexServlet",
                            },
                        },
                    },
                    events: {
                        "onReady": onReady,
                        "onDocumentStateChange": onDocumentStateChange,
                        'onRequestEditRights': onRequestEditRights,
                        "onError": onError,
                        "onOutdatedVersion": onOutdatedVersion,
                    }
                });
        };

其中 document屬性下的url地址 和 editorConfig屬性下的callbackUrl地址十分重要,也是在開發中需要重點關注的地方,很多報出的以下錯誤基本都是地址不對導致的。
OnlyOffice基礎實踐

重點說說這兩個配置的作用
1)document屬性下的url配置是onlyoffice的編輯服務用于獲取文檔的地址,也就是說,我們必須保證在docker中是必須能訪問到的地址, 通過wget命令嘗試在docker所在的服務器中是否能夠訪問。

OnlyOffice基礎實踐

2) editorConfig屬性下的callbackUrl配置是onlyoffice的編輯服務回調的,該回調的作用是告知你編輯后文檔的下載地址,以便更新原始文件,所以我們也得保證docker能夠訪問到該地址。我們可以自己編寫個用于回調的方法,例如:

public void saveFile(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        System.out.println("===saveeditedfile------------") ;
        try {
            writer = response.getWriter();
            Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
            String body = scanner.hasNext() ? scanner.next() : "";
            JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);
            System.out.println("===saveeditedfile:" + jsonObj.get("status")) ;
            /*
                0 - no document with the key identifier could be found,
                1 - document is being edited,
                2 - document is ready for saving,
                3 - document saving error has occurred,
                4 - document is closed with no changes,
                6 - document is being edited, but the current document state is saved,
                7 - error has occurred while force saving the document.
             * */
            if ((long) jsonObj.get("status") == 2) {
                /*
                 * 當我們關閉編輯窗口后,十秒鐘左右onlyoffice會將它存儲的我們的編輯后的文件,,此時status = 2,通過request發給我們,我們需要做的就是接收到文件然后回寫該文件。
                 * */
                /*
                 * 定義要與文檔存儲服務保存的編輯文檔的鏈接。當狀態值僅等于2或3時,存在鏈路。
                 * */
                String downloadUri = (String) jsonObj.get("url");
                System.out.println("====文檔編輯完成,現在開始保存編輯后的文檔,其下載地址為:" + downloadUri);
                //解析得出文件名
                String fileName = downloadUri.substring(downloadUri.lastIndexOf('/')+1);
                System.out.println("====下載的文件名:" + fileName);

                URL url = new URL(downloadUri);
                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                InputStream stream = connection.getInputStream();
        //更換為實際的路徑
                File savedFile = new File("e:\\");
                try (FileOutputStream out = new FileOutputStream(savedFile)) {
                    int read;
                    final byte[] bytes = new byte[1024];
                    while ((read = stream.read(bytes)) != -1) {
                        out.write(bytes, 0, read);
                    }
                    out.flush();
                }
                connection.disconnect();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        /*
         * status = 1,我們給onlyoffice的服務返回{"error":"0"}的信息,這樣onlyoffice會認為回調接口是沒問題的,這樣就可以在線編輯文檔了,否則的話會彈出窗口說明
         * */
        writer.write("{\"error\":0}");
    }

接下來再說說setting.properties配置文件,里面的配置內容如下:

filesize-max=5242880
storage-folder=app_data

files.docservice.viewed-docs=.pdf|.djvu|.xps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.ppsx|.txt
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.pptm|.ppt|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.rtf|.mht|.html|.htm|.epub
files.docservice.timeout=120000

files.docservice.url.converter=http://192.168.10.129/ConvertService.ashx
files.docservice.url.tempstorage=http://192.168.10.129/ResourceService.ashx
files.docservice.url.api=http://192.168.10.129/web-apps/apps/api/documents/api.js
files.docservice.url.preloader=http://192.168.10.129/web-apps/apps/api/documents/cache-scripts.html

其中的192.168.10.29是訪問onlyoffice document server的地址,如果訪問到,其結果應該如下:
OnlyOffice基礎實踐

以上就是使用onlyoffice的兩個關鍵點,文檔下載地址和onlyoffice回調地址

三:實踐(基于Springboot)
1,首先配置文件存放路徑和對應暴露的訪問地址

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // addResourceLocations指的是文件放置的目錄,addResourceHandler指的是對外暴露的訪問路徑
        registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("/file/").addResourceLocations("file:D:/uploadfile/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    /**
     * 統一處理沒啥業務邏輯處理的controller請求,實現代碼的簡潔
     * 
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index").setViewName("index");
    }

    /**
     * SpringMVC的路徑參數如果帶“.”的話,“.”后面的值將被忽略 .../pathvar/xx.yy 解析得到:xx
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // 通過設置為false使其可以接受"."后的但是
        configurer.setUseSuffixPatternMatch(false);
    }
}

此處我們將上傳文件保存在了“D:/uploadfile/”目錄下,該地址最好是在配置文件中配置,例如上面的setting.properties文件中。

2,創建用于編輯文檔的Controller

@Controller
public class EditorController {

    @RequestMapping("/EditorServlet")
    public ModelAndView index(HttpServletRequest request,HttpServletResponse response,Model model,ModelMap modelMap) throws Exception {
        String fileName = "";
        if (request.getParameterMap().containsKey("fileName")) {
             fileName = request.getParameter("fileName");
        }

        String fileExt = null;
        if (request.getParameterMap().containsKey("fileExt")) {
             fileExt = request.getParameter("fileExt");
        }

        if (fileExt != null) {
            try {
                DocumentManager.Init(request, response);
                fileName = DocumentManager.CreateDemo(fileExt);
            } catch (Exception ex) {
                return new ModelAndView(new FastJsonJsonView(),"Error: " + ex.getMessage(), ex) ;
            }
        }

        String mode = "";
        if (request.getParameterMap().containsKey("mode"))
        {
             mode = request.getParameter("mode");
        }
        Boolean desktopMode = !"embedded".equals(mode);

        FileModel file = new FileModel();
        file.SetTypeDesktop(desktopMode);
        file.SetFileName(fileName);

        System.out.println("==========EditorController==========");
        DocumentManager.Init(request, response);
        //要編輯的文件名
        model.addAttribute("fileName", fileName) ;
        //要編輯的文件類型
        model.addAttribute("fileType", FileUtility.GetFileExtension(fileName).replace(".", "")) ;
        //要編輯的文檔類型
        model.addAttribute("documentType",FileUtility.GetFileType(fileName).toString().toLowerCase()) ;
        //要編輯的文檔訪問url
        model.addAttribute("fileUri",DocumentManager.GetFileUri(fileName)) ;
        model.addAttribute("fileKey",ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName)) ;
        model.addAttribute("callbackUrl", DocumentManager.GetCallback(fileName)) ;
        model.addAttribute("serverUrl", DocumentManager.GetServerUrl()) ;
        model.addAttribute("editorMode", DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName)) && !"view".equals(request.getAttribute("mode")) ? "edit" : "view") ;
        model.addAttribute("editorUserId",DocumentManager.CurUserHostAddress(null)) ;

        model.addAttribute("type", desktopMode ? "desktop" : "embedded");
        model.addAttribute("docserviceApiUrl", ConfigManager.GetProperty("files.docservice.url.api"));
        model.addAttribute("docServiceUrlPreloader", ConfigManager.GetProperty("files.docservice.url.preloader")) ;
        model.addAttribute("currentYear", "2018") ;
        model.addAttribute("convertExts", String.join(",", DocumentManager.GetConvertExts())) ;
        model.addAttribute("editedExts", String.join(",", DocumentManager.GetEditedExts())) ;
        model.addAttribute("documentCreated", new SimpleDateFormat("MM/dd/yyyy").format(new Date())) ;
        model.addAttribute("permissionsEdit", Boolean.toString(DocumentManager.GetEditedExts().contains(FileUtility.GetFileExtension(fileName))).toLowerCase()) ;
        return new ModelAndView("editor") ;
    }
}

3,創建用于保存修改后文件的Controller

/*
 * 用于保存修改后的文件
 * */
@Controller
@RequestMapping("/savefilectrl")
public class SaveFileController {

    /**
     * 文檔編輯服務使用JavaScript API通知callbackUrl,向文檔存儲服務通知文檔編輯的狀態。文檔編輯服務使用具有正文中的信息的POST請求。
     * https://api.onlyoffice.com/editors/callback
     * 參數示例:
       {
            "actions": [{"type": 0, "userid": "78e1e841"}],
            "changesurl": "https://documentserver/url-to-changes.zip",
            "history": {
                "changes": changes,
                "serverVersion": serverVersion
            },
            "key": "Khirz6zTPdfd7",
            "status": 2,
            "url": "https://documentserver/url-to-edited-document.docx",
            "users": ["6d5a81d0"]
        }
     * @throws ParseException 
     */
    @RequestMapping("/saveeditedfile")
    public void saveFile(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        System.out.println("===saveeditedfile------------") ;
        try {
            writer = response.getWriter();
            Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
            String body = scanner.hasNext() ? scanner.next() : "";
            JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);
            System.out.println("===saveeditedfile:" + jsonObj.get("status")) ;
            /*
                0 - no document with the key identifier could be found,
                1 - document is being edited,
                2 - document is ready for saving,
                3 - document saving error has occurred,
                4 - document is closed with no changes,
                6 - document is being edited, but the current document state is saved,
                7 - error has occurred while force saving the document.
             * */
            if ((long) jsonObj.get("status") == 2) {
                /*
                 * 當我們關閉編輯窗口后,十秒鐘左右onlyoffice會將它存儲的我們的編輯后的文件,,此時status = 2,通過request發給我們,我們需要做的就是接收到文件然后回寫該文件。
                 * */

                /*
                 * 定義要與文檔存儲服務保存的編輯文檔的鏈接。當狀態值僅等于2或3時,存在鏈路。
                 * */
                String downloadUri = (String) jsonObj.get("url");
                System.out.println("====文檔編輯完成,現在開始保存編輯后的文檔,其下載地址為:" + downloadUri);
                //解析得出文件名
                String fileName = downloadUri.substring(downloadUri.lastIndexOf('/')+1);
                System.out.println("====下載的文件名:" + fileName);

                URL url = new URL(downloadUri);
                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                InputStream stream = connection.getInputStream();

                File savedFile = new File("e:\\");
                try (FileOutputStream out = new FileOutputStream(savedFile)) {
                    int read;
                    final byte[] bytes = new byte[1024];
                    while ((read = stream.read(bytes)) != -1) {
                        out.write(bytes, 0, read);
                    }
                    out.flush();
                }
                connection.disconnect();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        /*
         * status = 1,我們給onlyoffice的服務返回{"error":"0"}的信息,這樣onlyoffice會認為回調接口是沒問題的,這樣就可以在線編輯文檔了,否則的話會彈出窗口說明
         * */
        writer.write("{\"error\":0}");
    }
}

4,項目中使用的Freemarker,所以編輯頁面修改為

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>ONLYOFFICE</title>
        <link rel="icon" href="asstes/favicon.ico" type="image/x-icon" />
        <link rel="stylesheet" type="text/css" href="assets/css/editor.css" />

        <script type="text/javascript" src="${docserviceApiUrl}"></script>
        <script type="text/javascript" language="javascript">

        var docEditor;
        var fileName = "${fileName}";
        var fileType = "${fileType}";

        var innerAlert = function (message) {
            if (console && console.log)
                console.log(message);
        };

        var onReady = function () {
            innerAlert("Document editor ready");
        };

        var onDocumentStateChange = function (event) {
            var title = document.title.replace(/\*$/g, "");
            document.title = title + (event.data ? "*" : "");
        };

        var onRequestEditRights = function () {
            location.href = location.href.replace(RegExp("action=view\&?", "i"), "");
        };

        var onError = function (event) {
            if (event)
                innerAlert(event.data);
        };

        var onOutdatedVersion = function (event) {
            location.reload(true);
        };

        var сonnectEditor = function () {

            docEditor = new DocsAPI.DocEditor("iframeEditor",
                {
                    width: "100%",
                    height: "100%",
                    type: "${type}",
                    documentType: "${documentType}",

                    document: {
                        title:"${fileName}", 
                        url: "${fileUri}",
                        fileType: "${fileType}",
                        key: "${fileKey}",
                        info: {
                            author: "Me",
                            created: "${documentCreated}",
                        },

                        permissions: {
                            edit: ${permissionsEdit},
                            download: true,
                        }
                    },
                    editorConfig: {
                        mode: "${editorMode}",
                        lang: "en",
                        callbackUrl: "${callbackUrl}",

                        user: {
                            id: "${editorUserId}",
                            name: "John Smith",
                        },
                        embedded: {
                            saveUrl: "${fileUri}",
                            embedUrl: "${fileUri}",
                            shareUrl: "${fileUri}",
                            toolbarDocked: "top",
                        },
                        customization: {
                            about: true,
                            feedback: true,
                            goback: {
                                url: "${serverUrl}/IndexServlet",
                            },
                        },
                    },
                    events: {
                        "onReady": onReady,
                        "onDocumentStateChange": onDocumentStateChange,
                        'onRequestEditRights': onRequestEditRights,
                        "onError": onError,
                        "onOutdatedVersion": onOutdatedVersion,
                    }
                });
        };

        if (window.addEventListener) {
            window.addEventListener("load", сonnectEditor);
        } else if (window.attachEvent) {
            window.attachEvent("load", сonnectEditor);
        }

        function getXmlHttp() {
            var xmlhttp;
            try {
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (ex) {
                    xmlhttp = false;
                }
            }
            if (!xmlhttp && typeof XMLHttpRequest !== "undefined") {
                xmlhttp = new XMLHttpRequest();
            }
            return xmlhttp;
        }

    </script>

    </head>
    <body>
        <div class="form">
            <div id="iframeEditor"></div>
        </div>
    </body>
</html>

其Freemarker的配置

#設定ftl文件路徑
spring.freemarker.template-loader-path=classpath:/templates/freemarker
spring.freemarker.suffix=.html
spring.freemarker.content-type=text/html
spring.freemarker.templateEncoding=UTF-8

以上就是核心部分的代碼,重點是要保證配置準確。

至于docker和onlyoffice安裝過程就不贅述了,最后看下docker運行情況
OnlyOffice基礎實踐

附:onlyoffice安裝過程
1,安裝docer

yum install docker -y

2,啟動docker服務

systemctl start docker

3,拉取onlyoffice

docker pull onlyoffice/documentserver

4,啟動Document Server鏡像,并映射80端口至本地(前面個80)。

sudo docker run -i -t -d -p 80:80 onlyoffice/documentserver
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江口县| 海南省| 陇南市| 绵阳市| 桐乡市| 泰顺县| 海兴县| 福清市| 七台河市| 绵阳市| 阳东县| 乌鲁木齐县| 信阳市| 定日县| 永城市| 壶关县| 石屏县| 梅河口市| 巩义市| 封丘县| 化德县| 临沭县| 鄂伦春自治旗| 巩留县| 吕梁市| 治县。| 乌兰县| 博野县| 湾仔区| 永清县| 读书| 海城市| 桃园县| 尼勒克县| 红桥区| 丰镇市| 兰州市| 彰化市| 马龙县| 城口县| 莱西市|