我司目前使用的文档处理中心就是基于only office搭建的集群,个人觉得还是比较好用的。
1. 安装
官网:https://www.onlyoffice.com/zh/download.aspx
提供了多种安装方式,为了方便直接使用docker安装。
拉取only office镜像:
1
| docker pull onlyoffice/documentserver
|
启动docker容器:
1 2 3 4 5 6
| docker run -i -t -d -p 6831:80 --restart=always \ --name onlyoffice-document-server \ -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \ onlyoffice/documentserver
|
安装ftp服务:
1
| docker run -d -p 21:21 -p 20:20 -p 21100-21110:21100-21110 -v F:/OnlyOfficeFile:/home/vsftpd -e FTP_USER=lingxiao -e FTP_PASS=12345678 -e PASV_ADDRESS=192.168.26.123 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 --name vsftpd --restart=always fauria/vsftpd
|
-e FTP_USER=davion -e FTP_PASS=davion 添加一个初始化用户davion
PASV_MIN_PORT和PASV_MAX_PORT映射的是被动模式下端口使用范围
2. 下载最佳示例
下载地址:https://api.onlyoffice.com/editors/example/java
这个示例的代码看起来还是比较繁琐的,还用的servlet那套东西,而且由于是本地使用,docker访问宿主机网络有问题,于是我自己写了一个SpringBoot版本的。
SpringBoot版本github地址:https://github.com/lingxiaoplus/offfice
修改配置
源码下载下来,需要修改yml中的几个配置:
1 2 3 4 5 6 7
| office: filesizeMax: 5242880 saveRootPath: D:/OnlyOfficeFile baseUrl: http://localhost:6831 docService: url: callbackServer: http://192.168.170.113:8080/callback/office
|
其中saveRootPath改为你本地存在的一个目录,这个目录没啥用,只是作为一个临时文件目录。
baseUrl改为onlyoffice服务的ip+端口地址。
callbackServer修改成你本机的ip,作为回调接口,保存文件内容的时候,only office会调用,一定要确保only office能访问到你本机。不然会给出弹框提示,无法保存文件:

因为only office是装在docker中的,而docker和我本机用的不是同一个网络,only office没法下载本地的文件,所以我就直接把文件上传到七牛云oss,这里要配置一下七牛云:
1 2 3 4 5 6 7
| oss: type: qiniu accessKey: V_ZleIlYzHPjekmAuRvDkkM12f secretKey: U8SndxcceqMZGIKvhfPL3grP75cJlOH bucketName: office prefixDomain: http://oss.lingxiao.top rootPath: /onlyOffice
|
如果没有七牛云,也可以自己用minio本地搭一个对象存储服务,同样要保证文件链接是可访问的:
1 2 3 4 5 6 7
| oss: type: minio accessKey: admin secretKey: admin123456 bucketName: office prefixDomain: http://oss.lingxiao.top rootPath: /onlyOffice
|
docker搭建minio对象存储服务:
1 2 3 4 5 6 7
| docker run -p 9000:9000 --name minio_office \ -d --restart=always \ -e "MINIO_ACCESS_KEY=admin" \ -e "MINIO_SECRET_KEY=admin123456" \ -v D:\minio:/data \ -v D:\minio\config:/root/.minio \ minio/minio server /data
|
保证文件的链接是office可访问的,不然会出现下面的提示无法下载文件:

office的相关配置
office相关配置都是在前端中控制的,首先要引入only office的js:
1
| <script type="text/javascript" th:src="${docserviceApiUrl}"></script>
|
配置相关的都是用的他默认的:
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
| <script type="text/javascript" th:inline="javascript"> var doca; 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("mode=view\&?", "i"), ""); }; var onError = function (event) { if (event) innerAlert(event.data); };
var onOutdatedVersion = function (event) { location.reload(true); }; const file = {}; console.log("文件信息",file)
var сonnectEditor = function () { var config={ "document":{ "fileType": file.document.fileType, "key": file.document.key, "title": file.document.title, "url": file.document.url, "permissions": { "changeHistory": true, "comment": true, "copy": false, "download": true, "edit": file.editorConfig.editable, "fillForms": true, "modifyContentControl": true, "modifyFilter": true, "print": true, "rename": true, "review": true }, }, "documentType": file.documentType, "editorConfig": { "callbackUrl": file.editorConfig.callbackUrl, "customization":{ "forcesave":"true" }, "user": { "id": "78ele841", "name":"John Smith" }, "lang":"zh-CN", }, "height": "100%", "width": "100%" }; docEditor = new DocsAPI.DocEditor("iframeEditor", config); }; if (window.addEventListener) { window.addEventListener("load", сonnectEditor); } else if (window.attachEvent) { window.attachEvent("load", сonnectEditor); }
</script>
|
文件转换
有些文件不需要经过转换,就能直接预览的,比如pdf文件。但是如果是doc、xls、pptx这种类型的文件,就需要经过only office先转换一次,然后才能编辑。
所以文件上传的时候做一下判断,然后再看是否要传给only office做一次转换,转换完成之后将转换的文件从only office下载回来保存,下次预览就用这个转换后的文件做预览。
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
| @Override public ResponseResult<ConvertResult> convert(String fileName,String fileUrl) { String fileExt = fileUtil.getFileExtension(fileName); FileType fileType = fileUtil.getFileType(fileName); String internalFileExt = DocumentManager.getInternalExtension(fileType); if (documentManager.getViewedSuffixes().contains(fileExt)){ ConvertResult convertResult = new ConvertResult(); convertResult.setFileUrl(fileUrl); convertResult.setFileName(fileName); convertResult.setProgress(100); convertResult.setEndConvert(true); return ResponseResult.ok(convertResult); } if (!documentManager.getConvertSuffixes().contains(fileExt)) { throw new OfficeException("不支持的文件格式: "+ fileExt); } log.debug("开始文件转换: {}",fileUrl); String key = serviceConverter.generateRevisionId(fileUrl); ConvertResult convertResult = serviceConverter.getConvertedUri(fileUrl, fileExt, internalFileExt, key, true); if (!convertResult.getEndConvert()) { return ResponseResult.ok(convertResult); } String correctName = documentManager.getCorrectName(fileUtil.getFileNameWithoutExtension(fileName) + internalFileExt); try { File convertedFile = httpUtil.downloadFile(convertResult.getFileUrl(), documentManager.storagePath(correctName)); log.debug("文件转换成功,上传转换文件..."); OssFileInfo ossFileInfo = ossFileService.uploadFile(convertedFile, CONVERT_PATH,false); convertedFile.deleteOnExit(); log.debug("文件转换成功: {}",ossFileInfo); convertResult.setFileUrl(ossFileInfo.getPath()); return ResponseResult.ok(convertResult); } catch (IOException ex) { ex.printStackTrace(); throw new OfficeException(ex.getMessage()); } }
|
3. 总结
上面也只是涉及了文件编辑相关的,多人协作编辑还没涉及,所以博主也只了解文件编辑相关的原理。各位想深入理解的可以去官网看原文。