文章目錄
- onloyoffice歷史版本功能實現,版本恢復功能,編輯器功能實現 springboot+vue2
- 前提 需要注意把這個 (改成自己服務器的ip或者域名) 改成 自己服務器的域名或者地址
- 我使用的onloyoffice版本 8.1.3.4
- 1. onloyoffice服務器部署 搜索其他文章
- 2. 前段代碼 vue 2
- 2.1 需要注意把這個 (改成自己服務器的ip或者域名) 改成 自己服務器的域名或者地址
- 2.2. openedit getHistoryData 這兩個 是調用后端的 接口 改成自己項目的寫法 都是 post 請求
- 2.3 下面是整個頁面代碼 需要 別的頁面進入下面這個頁面 入參是 文件id
- 舉例
- 進入editer.vue 頁面的 頁面代碼 row.id 是文件id 也就是 onloyoffice 文件id
- 文件名字 editer.vue
- 3. 后端java 代碼
- 3.1 controller 代碼
- 3.2 service 代碼
- 3.3 serviceImpl 代碼
- 3.3公共方法代碼
- 4.效果圖
- 5.可以參考此文章優化代碼
onloyoffice歷史版本功能實現,版本恢復功能,編輯器功能實現 springboot+vue2
前提 需要注意把這個 (改成自己服務器的ip或者域名) 改成 自己服務器的域名或者地址
我使用的onloyoffice版本 8.1.3.4
1. onloyoffice服務器部署 搜索其他文章
2. 前段代碼 vue 2
2.1 需要注意把這個 (改成自己服務器的ip或者域名) 改成 自己服務器的域名或者地址
2.2. openedit getHistoryData 這兩個 是調用后端的 接口 改成自己項目的寫法 都是 post 請求
2.3 下面是整個頁面代碼 需要 別的頁面進入下面這個頁面 入參是 文件id
舉例
進入editer.vue 頁面的 頁面代碼 row.id 是文件id 也就是 onloyoffice 文件id
//row.id 是文件id 也就是 onloyoffice 文件id
// /only/editer/ 這是頁面路由的地址需要在路由里面配置
//頁面
openFile(row) {window.open('#/only/editer/' + row.id,'_blank');},
文件名字 editer.vue
<template><div><div id="onlyoffice-container" ref="editorContainer"></div></div>
</template><script>
import {openedit, getHistoryData, restoreVersion, editHistory} from '@/http/http';export default {name: 'OnlyOfficeEditor',props: {isEdit: {type: Boolean,default: true}},data() {return {docEditor: null,currentVersion: null,fileToken: null,historyData: null,historys: [],historyList: []};},mounted() {this.loadScript().then(() => {this.initEditor();});},methods: {// 加載腳本loadScript() {return new Promise((resolve, reject) => {const scriptId = "onlyoffice-api-script";if (!document.getElementById(scriptId)) {const script = document.createElement('script');script.id = scriptId;script.src = "https://(替換為自己的域名或者ip)/ds-vpath/web-apps/apps/api/documents/api.js";script.type = "text/javascript";script.onload = resolve;script.onerror = reject;document.head.appendChild(script);} else {resolve();}});},// 初始化編輯器initEditor() {if (this.docEditor) {this.docEditor.destroyEditor();this.docEditor = null;}openedit({"fileId": this.$route.params.id}).then((res) => {if (res.code === 200) {const config = res.data.openedit;config.events = this.getEditorEvents();this.docEditor = new window.DocsAPI.DocEditor(this.$refs.editorContainer.id, config);}}).catch(this.handleError);},// 獲取編輯器事件配置getEditorEvents() {return {onRequestHistory: this.handleRequestHistory,onRequestHistoryClose: this.handleRequestHistoryClose,onRequestHistoryData: this.handleRequestHistoryData,onRequestRestore: this.handleRequestRestore};},// 處理請求歷史記錄事件handleRequestHistory() {editHistory({"fileId": this.$route.params.id}).then((res) => {if (res.code === 200) {const historyList = res.data.editHistory;const fileToken = res.data.fileToken;const currentVersion = historyList[historyList.length - 1].version;this.docEditor.refreshHistory({currentVersion,token: fileToken,history: historyList});}}).catch(this.handleError);},// 處理關閉歷史記錄事件handleRequestHistoryClose() {document.location.reload();},// 處理請求歷史記錄數據事件handleRequestHistoryData(event) {const version = event.data;getHistoryData({"fileId": this.$route.params.id, "version": version}).then((res) => {if (res.code === 200) {const historyData = res.data.historyData;this.docEditor.setHistoryData(historyData);}}).catch(this.handleError);},// 處理版本恢復事件handleRequestRestore(event) {const version = event.data.version;restoreVersion({"fileId": this.$route.params.id, "version": version}).then((res) => {if (res.code === 200) {const historyList = res.data.editHistory;const currentVersion = historyList[historyList.length - 1].version;this.docEditor.refreshHistory({currentVersion,history: historyList});}}).catch(this.handleError);},// 統一錯誤處理handleError(err) {console.log(err);},// 銷毀編輯器destroyEditor() {if (this.docEditor) {this.docEditor.destroyEditor();this.docEditor = null;}if (this.DocsAPIInterval) {clearInterval(this.DocsAPIInterval);}}},beforeDestroy() {this.destroyEditor();},beforeRouteLeave(to, from, next) {this.destroyEditor();next();},
};
</script><style>
iframe {border: none;width: 100%;height: 100vh;
}
</style>
3. 后端java 代碼
3.1 controller 代碼
@PostMapping("/openedit")public RestResultDTO openedit(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {try {if (CommonFunctions.isEmpty(params.getFileId())) {throw new BusinessServiceException("非空校驗失敗");}Map<String, Object> resultMap = onlyofficeService.openedit(params);return RestResultDTO.success(resultMap);} catch (Exception e) {LOGGER.error("openedit 方法發生異常: ", e);return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());}}
@PostMapping("/getHistoryData")public RestResultDTO getHistoryData(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {try {if (CommonFunctions.isEmpty(params.getFileId()) || CommonFunctions.isEmpty(params.getVersion())) {throw new BusinessServiceException("非空校驗失敗");}Map<String, Object> resultMap = onlyofficeService.getHistoryData(params);return RestResultDTO.success(resultMap);} catch (Exception e) {LOGGER.error("openedit 方法發生異常: ", e);return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());}}
/*** 還原版本** @return* @request: fileId personId*/@PostMapping("/restoreVersion")public RestResultDTO restoreVersion(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {try {if (CommonFunctions.isEmpty(params.getFileId()) || CommonFunctions.isEmpty(params.getVersion())) {throw new BusinessServiceException("非空校驗失敗");}Map<String, Object> resultMap = onlyofficeService.restoreVersion(params);return RestResultDTO.success(resultMap);} catch (Exception e) {LOGGER.error("restoreVersion 方法發生異常: ", e);return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());}}
/*** 修改歷史** @return* @request: fileId personId*/@PostMapping("/editHistory")public RestResultDTO editHistory(HttpServletRequest request, @RequestBody OnlyofficeRequestDTO params) {try {if (CommonFunctions.isEmpty(params.getFileId())) {throw new BusinessServiceException("非空校驗失敗");}Map<String, Object> resultMap = onlyofficeService.editHistory(params);return RestResultDTO.success(resultMap);} catch (Exception e) {LOGGER.error("editHistory 方法發生異常: ", e);return RestResultDTO.error(ResponseCodeDTO.INTERNAL_SERVER_ERROR, e.getMessage());}}
3.2 service 代碼
Map<String, Object> openedit(OnlyofficeRequestDTO params);
//獲取文件的初始化配置Map<String, Object> getHistoryData(OnlyofficeRequestDTO params);
Map<String, Object> restoreVersion(OnlyofficeRequestDTO params);
Map<String, Object> editHistory(OnlyofficeRequestDTO params);
3.3 serviceImpl 代碼
@Overridepublic Map<String, Object> openedit(OnlyofficeRequestDTO params) {String fileId = params.getFileId();String permissionType = "";JSONObject onlyOfficeConfig = null;try {String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_SHAREFILE_URL + fileId + "/openedit", null, null, "UTF-8", "get");JSONObject resJsonObject = JSONObject.parseObject(result);if (CollectionUtils.isEmpty(resJsonObject)) {throw new BusinessServiceException("獲取配置文件異常");} else if (resJsonObject.getInteger("statusCode") == 200) {onlyOfficeConfig = resJsonObject.getJSONObject("response");} else if (resJsonObject.getInteger("statusCode") == 500) {throw new BusinessServiceException(resJsonObject.getJSONObject("error").getString("message"));} else {throw new BusinessServiceException("獲取配置文件異常");}//只讀if ("4".equals(permissionType)) {onlyOfficeConfig.getJSONObject("editorConfig").put("mode", "view");}} catch (Exception e) {LOGGER.error("解析JSON響應失敗", e);throw new BusinessServiceException("", e);}// 使用 Map 封裝多個 JSON 對象Map<String, Object> resultMap = new HashMap<>();resultMap.put("openedit", onlyOfficeConfig);return resultMap;}
@Overridepublic Map<String, Object> getHistoryData(OnlyofficeRequestDTO params) {String fileId = params.getFileId();String version = params.getVersion();JSONObject responseArray = null;try {String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL + "/edit-diff-url?fileId=" + fileId + "&version=" + version, null, null, "UTF-8", "get");responseArray = JSONObject.parseObject(result);if (CollectionUtils.isEmpty(responseArray)) {throw new BusinessServiceException("獲取配置文件異常");}} catch (Exception e) {LOGGER.error("解析JSON響應失敗", e);throw new BusinessServiceException("", e);}// 使用 Map 封裝多個 JSON 對象Map<String, Object> resultMap = new HashMap<>();resultMap.put("historyData", responseArray);return resultMap;}
@Overridepublic Map<String, Object> restoreVersion(OnlyofficeRequestDTO params) {String fileId = params.getFileId();String version = params.getVersion();JSONArray responseArray = null;try {String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL + "/restore-version?fileId=" + fileId + "&version=" + version, null, null, "UTF-8", "put");// 嘗試解析為 JSONArrayJSONArray resJsonArray = JSONArray.parseArray(result);if (CollectionUtils.isEmpty(resJsonArray)) {throw new BusinessServiceException("獲取配置文件異常");}} catch (Exception e) {LOGGER.error(" 解析JSON響應失敗", e);throw new BusinessServiceException("", e);}Map<String, Object> stringObjectMap = this.editHistory(params);return stringObjectMap;}
@Overridepublic Map<String, Object> editHistory(OnlyofficeRequestDTO params) {String fileId = params.getFileId();JSONArray responseArray = null;try {String result = HttpUtils.executeRequestOnlyoffice(HttpUtils.O_FILES_URL + "/edit-history?fileId=" + fileId, null, null, "UTF-8", "get");// 嘗試解析為 JSONArrayJSONArray resJsonArray = JSONArray.parseArray(result);if (CollectionUtils.isEmpty(resJsonArray)) {throw new BusinessServiceException("獲取配置文件異常");}responseArray = resJsonArray;} catch (Exception e) {LOGGER.error(" 解析JSON響應失敗", e);throw new BusinessServiceException("", e);}// 使用 Map 封裝多個 JSON 對象Map<String, Object> resultMap = new HashMap<>();try {resultMap.put("fileToken",HttpUtils.renovateAuthorizationToken());} catch (Exception e) {LOGGER.error(" 獲取token失敗", e);throw new BusinessServiceException("", e);}resultMap.put("editHistory", responseArray);return resultMap;}
3.3公共方法代碼
/*** 根據請求類型執行POST或PUT請求*/public static String executeRequestOnlyoffice(String url, Map<String, Object> params, Map<String, String> headers, String encoding, String requestType) throws Exception {Map<String, String> headersCover = new HashMap<>();String authorizationToken = getAuthorizationToken();//覆蓋默認請求頭headersCover.put("Authorization", authorizationToken);headersCover.put("Accept", "application/json");headersCover.put("Content-Type", "application/json");if (headers != null) {for (Map.Entry<String, String> entry : headers.entrySet()) {headersCover.put(entry.getKey(), entry.getValue());}}switch (requestType.toLowerCase()) {case "get":return executeGetRequestCommon(url, params, headersCover, encoding);case "post":return executePostRequestCommon(url, params, headersCover, encoding);case "put":return executePutRequestCommon(url, params, headersCover, encoding);case "delete":return executeDeleteRequestCommon(url, params, headersCover, encoding);default:throw new IllegalArgumentException("Unsupported request type: " + requestType);}}
/*** 獲取授權Token*/public static synchronized void refreshAuthorizationToken() throws Exception {Map<String, Object> params = new HashMap<>();params.put("userName", "");//輸入onloyoffice 登錄用戶名params.put("password", "");//輸入onloyoffice登錄密碼Map<String, String> headers = new HashMap<>();headers.put("Accept", "application/json");headers.put("Content-Type", "application/json");String result = executePostRequestCommon(HttpUtils.O_AUTH_URL, params, headers, "UTF-8");JSONObject jsonObject = JSONObject.parseObject(result);HttpUtils.authorizationToken = "Bearer " + jsonObject.getJSONObject("response").getString("token");}// 獲取Token的方法@PostConstructpublic static String getAuthorizationToken() throws Exception {if (CommonFunctions.isEmpty(HttpUtils.authorizationToken)) {refreshAuthorizationToken();}return HttpUtils.authorizationToken;}
/*** 執行GET通用請求*/public static String executeGetRequestCommon(String url, Map<String, Object> params, Map<String, String> headers, String encoding) throws Exception {// 創建一個帶有默認配置的HttpClient,并設置超時時間RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) // 連接超時時間.setSocketTimeout(10000) // 讀取超時時間.build();try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {// 構建帶有查詢參數的URLif (params != null && !params.isEmpty()) {StringBuilder queryString = new StringBuilder(url);if (!url.contains("?")) {queryString.append("?");} else {queryString.append("&");}for (String key : params.keySet()) {queryString.append(key).append("=").append(params.get(key)).append("&");}// 去掉最后一個多余的&if (queryString.toString().endsWith("&")) {queryString.setLength(queryString.length() - 1);}url = queryString.toString();}HttpGet httpGet = new HttpGet(url);// 添加自定義頭信息if (headers != null) {for (Map.Entry<String, String> entry : headers.entrySet()) {httpGet.addHeader(entry.getKey(), entry.getValue());}}// 執行請求并獲取響應try (CloseableHttpResponse response = httpClient.execute(httpGet)) {HttpEntity entity = response.getEntity();return entity != null ? EntityUtils.toString(entity, encoding != null ? encoding : "UTF-8") : null;}} catch (IOException e) {logger.error("Error executing GET request to URL: {}. Exception: {}", url, e.getMessage(), e);throw e;}}
public static String O_FILES_URL = "https://(自己服務器ip或者域名)/Products/Files/Services/WCFService/service.svc"public static String O_SHAREFILE_URL = "https://(自己服務器ip或者域名)/api/2.0/files/file/"
/*** 獲取授權Token* @return 授權Token字符串* @throws Exception 如果請求或解析失敗*/public static String renovateAuthorizationToken() throws Exception {// 構造請求參數Map<String, Object> params = new HashMap<>();params.put("userName", "");//輸入onloyoffice 登錄用戶名params.put("password", "");//輸入onloyoffice登錄密碼// 構造請求頭Map<String, String> headers = new HashMap<>();headers.put("Accept", "application/json");headers.put("Content-Type", "application/json");// 執行POST請求并獲取結果String result = executePostRequestCommon(HttpUtils.O_AUTH_URL, params, headers, "UTF-8");// 解析JSON結果JSONObject jsonObject = JSONObject.parseObject(result);return jsonObject.getJSONObject("response").getString("token");}
4.效果圖
5.可以參考此文章優化代碼
https://www.cnblogs.com/gamepen/p/17849005.html