本文主要是介绍Java集成Onlyoffice的示例代码及场景分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Java集成Onlyoffice的示例代码及场景分析》:本文主要介绍Java集成Onlyoffice的示例代码及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要...
需求场景:实现文档的在线编辑,团队协作
总结:两个接口 + 前端页面 + 配置项
接口1:一个接口,将onlyoffice前端需要的配置项返回给前端(文档地址、是否编辑模式...)
前端:接受配置项,集成onlyoffice的js文件,展示文档
接口2:一个回调接口,用于onlyoffice前端的文件保存后的调用方法
一些配置项:application 里面配置 服务器的地址,token 等 ,maven 引入依赖。
文章结尾提供官方示例代码:
注意:
1、docs-integration-sdk 2024年12月,国内腾讯的中央仓库下不了,我不想换镜像,就注释掉,用的离线包。
2、加了一个pom 的依赖,不加启动报错
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
接口1:文档地址必须可以让onlyofficeu所在的服务器可以访问到,可以是本地磁盘的映射,可以是 MINIO。文档应当还有一个唯一的Key;
public String index(@RequestParam("fileName") final String fileName, @RequestParam(value = "action", required = false) final String actionParam, @RequestParam(value = "type", required = false) final String typeParam, @RequestParam(value = "actionLink", required = false) final String actionLink, @CookieValue(value = "uid") final String uid, @CookieValue(value = "ulang") final String lang, final Model model) throws JsonProcessingException { Action action = null; Type type = Type.DESKTOP; Locale locale = new Locale("en"); if (actionParam != null) { action = Action.valueOf(actionParam); } if (typeParam != null) { type = Type.valueOf(typeParam.toUpperCase()); } List<String> langsAndKeys = Arrays.asList(langs.split("\\|")); for (String langAndKey : langsAndKeys) { String[] couple = langAndKey.split(":"); if (couple[0].equals(lang)) { String[] langAndCountry = couple[0].split("-"); locale = new Locale(langAndCountry[0], langAndCountry.length > 1 ? langAndCountry[1] : ""); } } Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid)); // if the user is not present, return the ONLYOFFICE start page if (!optionalUser.isPresent()) { return "index.html"; } Config config = configService.createConfig( fileName, action, type ); JSONObject actionData = null; if (actionLink != null && !actionLink.isEmpty()) { actionData = new JSONObject(actionLink); } config.getEditorConfig().setActionLink(actionData); config.getEditorConfig().setLang(locale.toLanguageTag()); model.addAttribute("model", config); // create the document service api URL and add it to the model model.addAttribute("docserviceApiUrl", urlManager.getDocumentServerApiUrl()); // get an image and add it to the model model.addAttribute("dataInsertImage", getInsertImage()); // get a document for comparison and add it to the model model.addAttribute("dataDocument", getCompareFile()); // get recipients data for mail merging and add it to the model model.addAttribute("datASPreadsheet", getSpreadsheet()); // get user data for mentions and add it to the model model.addAttribute("usersForMentions", getUserMentions(uid)); model.addAttribute("usersInfo", getUsersInfo(uid)); // get user data for protect and add it to the model model.addAttribute("usersForProtect", getUserProtect(uid)); return "editor.html"; }
接口2:回调保存,其中的 {\"error\":\"0\"} 是告诉onlyOffice回调接口是没问题的,这样就可以在线编辑文档了,否则的话会弹出窗口说明。
public String track(final HttpServletRequest request, // track file changes @RequestParam("fileName") final String fileName, @RequestParam("userAddress") final String userAddress, @RequestBody final Callback body) { Callback callback; try { String bodyString = objectMapper .writeValueAsString(body); // write the request body to the object mapper as a string if (bodyString.isEmpty()) { // if the request body is empty, an error occurs throw new RuntimeException("{\"error\":1,\"message\":\"Request payload is empty\"}"); } String authorizationHeader = request.getHeader(settingsManager.getSecurityHeader()); callback = callbackService.verifyCallback(body, authorizationHeader); callbackService.processCallback(callback, fileName); } catch (Exception e) { String message = e.getMessage(); if (!message.contains("\"error\":1")) { e.printStackTrace(); } return message; } return "{\"error\":\"0\"}"; }
前端展示
<!DOCTYPE html> <html XMLns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-Scalable=no, minimal-ui" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="NcfVJEWmobile-web-app-capable" content="yes" /> <!-- * * (c) Copyright Ascensio System SIA 2024 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * --> <title>ONLYOFFICE</title> <link rel="icon" th:href="@{/css/img/{icon}.ico(icon=${model.getDocumentType()})}" rel="external nofollow" type="image/x-icon"/> <link rel="stylesheet" type="text/css" href="css/editor.css" rel="external nofollow" /> <script type="text/Javascript" th:src="@{${docserviceApiUrl}}"></script> <script th:inline="javascript"> var docEditor; var config; var innerAlert = function (message, inEditor) { if (console && console.log) console.log(message); if (inEditor && docEditor) docEditor.showMessage(message); }; // the application is loaded into the browser var onAppReady = function () { innerAlert("Document editor ready"); }; // the document is modified var onDocumentStateChange = function (event) { var title = document.title.replace(/\*$/g, ""); document.title = title + (event.data ? "*" : ""); }; // the user is trying to switch the document from the androidviewing into the editing mode var onRequestEditRights = function () { location.href = location.href.replace(RegExp("\&?action=\\w+", "i"), "") + "&action=edit"; }; // an error or some other specific event occurs var onError = function (event) { if (event) innerAlert(event.data); }; // the document is opened for editing with the old document.key value var onOutdatedVersion = function (event) { location.reload(true); }; // replace the link to the document which contains a bookmark var replaceActionLink = function(href, linkParam) { var link; var actionIndex = href.indexOf("&actionLink="); if (actionIndex != -1) { var endIndex = href.indexOf("&", actionIndex + "&actionLink=".length); if (endIndex != -1) { link = href.substring(0, actionIndex) + href.substring(endIndex) + "&actionLink=" python+ encodeURIComponent(linkParam); } else { link = href.substring(0, actionIndex) + "&actionLink=" + encodeURIComponent(linkParam); } } else { link = href + "&actionLink=" + encodeURIComponent(linkParam); } return link; } // the user is trying to get link for opening the document which contains a bookmark, scrolling to the bookmark position var onMakeActionLink = function (event) { var actionData = event.data; var linkParam = JSON.stringify(actionData); docEditor.setActionLink(replaceActionLink(location.href, linkParam)); }; // the meta information of the document is changed via the meta command var onMetaChange = function (event) { if (event.data.favorite !== undefined) { var favorite = !!event.data.favorite; var title = document.title.replace(/^\☆/g, ""); document.title = (favorite ? "☆" : "") + title; docEditor.setFavorite(favorite); } innerAlert("onMetaChange: " + JSON.stringify(event.data)); }; var dataInsertImage = [[${dataInsertImage}]]; // the user is trying to insert an image by clicking the Image from Storage button var onRequestInsertImage = function(event) { const temp = Object.assign({}, {"c": event.data.c}, dataInsertImage); docEditor.insertImage(temp); }; var dataDocument = [[${dataDocument}]]; // the user is trying to select document for comparing by clicking the Document from Storage button var onRequestSelectDocument = function(event) { const temp = Object.assign({"c": event.data.c}, JSON.parse(dataDocument)); docEditor.setRequestedDocument(temp); }; var dataSpreadsheet = [[${dataSpreadsheet}]]; // the user is trying to select recipients data by clicking the Mail merge button var onRequestSelectSpreadsheet = function (event) { const temp = Object.assign({"c": event.data.c}, JSON.parse(dataSpreadsheet)); docEditor.setRequestedSpreadsheet(temp); }; config = [[${model}]]; if (config.editorConfig.user.name == "Anonymous") { config.editorConfig.user.name = ""; } var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button var title = event.data.title; var url = event.data.url; var data = { title: title, url: url }; let xhr = new XMLHttpRequest(); xhr.open("POST", "saveas"); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(data)); xhr.onload = function () { innerAlert(xhr.responseText); innerAlert(JSON.parse(xhr.responseText).file, true); } }; var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button innerAlert("onRequestRename: " + JSON.stringify(event.data)); var newfilename = event.data; var data = { fileName: newfilename, fileKey: config.document.key, fileType: config.document.fileType }; let xhr = new XMLHttpRequest(); xhr.open("POST", "rename"); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(data)); xhr.onload = function () { innerAlert(xhr.responseText); } }; var onRequestOpen = function(event) { // user open external data source innerAlert("onRequestOpen"); var windowName = event.data.windowName; requestReference(event.data, function (data) { if (data.error) { var winEditor = window.open("", windowName); winEditor.close(); innerAlert(data.error, true); return; } var link = data.link; window.open(link, windowName); }); }; var onRequestReferenceData = function(event) { // user refresh external data source innerAlert("onRequestReferenceData"); requestReference(event.data, function (data) { docEditor.setReferenceData(data); }); }; var requestReference = function(data, callback) { innerAlert(data); let xhr = new XMLHttpRequest(); xhr.open("POST", "reference"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify(data)); xhr.onload = function () { innerAlert(xhr.responseText); callback(JSON.parse(xhr.responseText)); } }; var onRequestHistory = function () { var xhr = new XMLHttpRequest(); xhr.open("GET", "history?fileName=" + config.document.title, false); xhr.send(); if (xhr.status == 200) { var historyInfo = JSON.parse(xhr.responseText); docEditor.refreshHistory(historyInfo); } }; var onRequestHistoryData = function (event) { var version = event.data; var historyDataUri = "historydata?fileName=" + config.document.title + "&version=" + version; var xhr = new XMLHttpRequest(); xhr.open("GET", historyDataUri, false); xhr.send(); if (xhr.status == 200) { var historyData = JSON.parse(xhr.responseText); docEditor.setHistoryData(historyData); } }; var onRequestHistoryClose = function() { document.location.reload(); }; function onRequestRestore(event) { const query = new URLSearchParams(window.location.search) const pajsyload = { fileName: query.get('fileName'), version: event.data.version } const request = new XMLHttpRequest() request.open('PUT', 'restore') request.setRequestHeader('Content-Type', 'application/json') request.send(JSON.stringify(payload)) request.onload = function () { const response = JSON.parse(request.responseText); if (response.success && !response.error) { var historyInfoUri = "history?fileName=" + config.document.title; var xhr = new XMLHttpRequest(); xhr.open("GET", historyInfoUri, false); xhr.send(); if (xhr.status == 200) { var historyInfo = JSON.parse(xhr.responseText); docEditor.refreshHistory(historyInfo); } } else { innerAlert(response.error); } } }; var onRequestUsers = function (event) { if (event && event.data) { var c = event.data.c; } switch (c) { case "info": users = []; var allUsers = [[${usersInfo}]]; for (var i = 0; i < event.data.id.length; i++) { for (var j = 0; j < allUsers.length; j++) { if (allUsers[j].id == event.data.id[i]) { users.push(allUsers[j]); break; } } } break; case "protect": var users = [[${usersForProtect}]]; break; default: users = [[${usersForMentions}]]; } docEditor.setUsers({ "c": c, "users": users, }); }; var onRequestSendNotify = function(event) { // the user is mentioned in a comment event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink)); var data = JSON.stringify(event.data); innerAlert("onRequestSendNotify: " + data); }; config.width = "100%"; config.height = "100%"; config.events = { "onAppReady": onAppReady, "onDocumentStateChange": onDocumentStateChange, "onError": onError, "onOutdatedVersion": onOutdatedVersion, "onMakeActionLink": onMakeActionLink, "onMetaChange": onMetaChange, "onRequestInsertImage": onRequestInsertImage, "onRequestSelectDocument": onRequestSelectDocument, "onRequestSelectSpreadsheet": onRequestSelectSpreadsheet }; if (config.editorConfig.user.id != 4) { // add mentions for not anonymous users config.events['onRequestUsers'] = onRequestUsers; config.events['onRequestSaveAs'] = onRequestSaveAs; // the user is mentioned in a comment config.events['onRequestSendNotify'] = onRequestSendNotify; // prevent file renaming for anonymous users config.events['onRequestRename'] = onRequestRename; config.events['onRequestReferenceData'] = onRequestReferenceData; // prevent switch the document from the viewing into the editing mode for anonymous users config.events['onRequestEditRights'] = onRequestEditRights; config.events['onRequestOpeandroidn'] = onRequestOpen; config.events['onRequestHistory'] = onRequestHistory; config.events['onRequestHistoryData'] = onRequestHistoryData; if (config.editorConfig.user.id != 3) { config.events['onRequestHistoryClose'] = onRequestHistoryClose; config.events['onRequestRestore'] = onRequestRestore; } } var onnectEditor = function () { docEditor = new DocsAPI.DocEditor("iframeEditor", config); }; if (window.addEventListener) { window.addEventListener("load", onnectEditor); } else if (window.attachEvent) { window.attachEvent("load", onnectEditor); } </script> </head> <body> <div class="form"> <div id="iframeEditor"></div> </div> </body> </html>
完整代码可以下载,不搞VIP、付费
到此这篇关于Java集成Onlyoffice的文章就介绍到这了,更多相关Java集成Onlyoffice内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!
这篇关于Java集成Onlyoffice的示例代码及场景分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!