vue+onlyOffice+java : 集成在线编辑word并保存
1.docker部署onlyOffice
1.1拉取最新版onlyOffice镜像
sudo docker pull onlyoffice/documentserver
1.2运行以下命令运行容器
其中 -v 后的第一部分是挂载自己的linux的哪个目录
# 启动docker容器,默认启动端口为80,可以进行修改 docker run -i -t -d -e TZ="Asia/Shanghai" -p 6831:80 --restart=always \-v /usr/local/docker/document/logs:/var/log/onlyoffice \-v /usr/local/docker/document/data:/var/www/onlyoffice/Data \-v /usr/local/docker/document/lib:/var/lib/onlyoffice \-v /usr/local/docker/document/db:/var/lib/postgresql onlyoffice/documentserver
运行完容器后开始编写代码
2.前端vue代码:
2.1public文文件夹下index.html引入对应的脚本
其中的ip地址和端口改成自己的
<script type='text/javascript' src='http://192.168.59.164:6831/web-apps/apps/api/documents/api.js'></script>
2.2 vue组件代码
<!--onlyoffice 编辑器--> <template><div id='vabOnlyOffice'></div> </template><script> export default {name: 'VabOnlyOffice',props: {option: {type: Object,default: () => {return {}},},},data() {return {doctype: '',docEditor: null,}},beforeDestroy() {if (this.docEditor !== null) {this.docEditor.destroyEditor();this.docEditor = null;}},watch: {option: {handler: function(n) {this.setEditor(n)this.doctype = this.getFileType(n.fileType)},deep: true,},},mounted() {if (this.option.url) {this.setEditor(this.option)}},methods: {async setEditor(option) {if (this.docEditor !== null) {this.docEditor.destroyEditor();this.docEditor = null;}this.doctype = this.getFileType(option.fileType)let config = {document: {//后缀fileType: option.fileType,key: option.key ||'',title: option.title,permissions: {edit: option.isEdit,//是否可以编辑: 只能查看,传falseprint: option.isPrint,download: false,// "fillForms": true,//是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。// "review": true //跟踪变化},url: option.url,},documentType: this.doctype,editorConfig: {callbackUrl: option.editUrl,//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置lang: option.lang,//语言设置//定制customization: {autosave: false,//是否自动保存chat: false,comments: false,help: false,// "hideRightMenu": false,//定义在第一次加载时是显示还是隐藏右侧菜单。 默认值为false//是否显示插件plugins: false,},user:{id:option.user.id,name:option.user.name},mode:option.model?option.model:'edit',},width: '100%',height: '100%',token:option.token||''}// eslint-disable-next-line no-undef,no-unused-varsthis.docEditor = new DocsAPI.DocEditor('vabOnlyOffice', config)},getFileType(fileType) {let docType = ''let fileTypesDoc = ['doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps',]let fileTypesCsv = ['csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx',]let fileTypesPPt = ['fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',]if (fileTypesDoc.includes(fileType)) {docType = 'text'}if (fileTypesCsv.includes(fileType)) {docType = 'spreadsheet'}if (fileTypesPPt.includes(fileType)) {docType = 'presentation'}return docType}}, } </script>
2.3父组件中开始引用
要记得注册组件
<div class='qualityManual-container'><el-dialog :visible.sync="openOffice" width="800px" height="800px" append-to-body ><div class='qualityManual-container-office'><only-office :option='option' /></div></el-dialog></div>
对应的data中的属性:
openOffice:false,//参考vabOnlyOffice组件参数配置option: {key:"",url: '',isEdit: '',fileType: '',title: '',lang: '',isPrint: '',user: { id:null,name:''}},
对应的method中添加方法(这个方法可以在需要的地方引用):
需要注意的是,这里的ip必须这样填(自己天自己的),因为作为docker运行的onlyoffice,需要这样访问本地linux服务器中的服务程序
注:(自己在本地测试时无法通过localhost进行测试运行)
modifyTem(row){this.getFile(row.id)},getFile(id) {this.openOffice = truethis.show = false// getAction('/file/selectById', { id: this.id }).then(res => {this.option.isEdit = true // https://dsgrcdnblobprod5u3.azureedge.net/catalog-assets/zh-cn/a32a147f-1f69-4fd5-8a39-c25b2a0093e8/tf67429532_wac-987650ec15fa.docxthis.option.lang = 'zh-CN'this.option.url = 'http://192.168.59.164:8080/notemode/notemodeltypeenum/download/'+idthis.option.title = '笔录模板'this.option.fileType = 'docx'this.option.isPrint = falsethis.option.user= { id:12,name:'张三'}this.option.editUrl = "http://192.168.59.164:8080/notemode/notemodeltypeenum/save/"+id// this,option.key="11111"// })},close() {this.show = false},
对应的样式
<style > .qualityManual-container-office {width: 100%; /* 确保容器宽度充满整个父元素 */height: 800px; /* 根据需要调整高度 */overflow: hidden; /* 避免内部内容溢出 */ }</style>
3.对应的后端代码
1.dowload 方法是作为流进行文件数据的返回
2.save方法是对在线编辑后对于word的保存回调方法,在vue中有对应url回调地址的设置选项
注意:回调的时候,onlyOffice是通过一个地址(url)让你进行去下载。
有一些是测试时的代码,没有删掉,请大家注意甄别。
@GetMapping("/download/{id}")public void download(@PathVariable("id")Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {Notemodeltypeenum notemodeltypeenum = notemodeltypeenumService.selectNotemodeltypeenumByID(id);String filePath = "/a.docx";int profileIndex = notemodeltypeenum.getContentStr().indexOf("/profile") + "/profile".length();String subPath = notemodeltypeenum.getContentStr().substring(profileIndex);filePath = RuoYiConfig.getProfile()+subPath;//本地文件 // String configPath = RuoYiConfig.getAttachPath(); // filePath = configPath + attachment.getVirtualpath();File file = new File(filePath);if (file.exists()) {// String filename = attachment.getFilename();response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("a.docx", "utf-8"));response.setCharacterEncoding("utf-8");response.setContentLength((int) file.length());byte[] buff = new byte[(int) file.length()];BufferedInputStream bufferedInputStream = null;OutputStream outputStream = null;try {outputStream = response.getOutputStream();bufferedInputStream = new BufferedInputStream(new FileInputStream(file));int i = 0;while ((i = bufferedInputStream.read(buff)) != -1) {outputStream.write(buff, 0, i);outputStream.flush();}} catch (IOException e) {e.printStackTrace();} finally {try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}}}@PostMapping("/save/{id}")public void save(@PathVariable("id")Long id,@RequestParam Map<String, String> map, HttpServletRequest request, HttpServletResponse response) {Notemodeltypeenum notemodeltypeenum = notemodeltypeenumService.selectNotemodeltypeenumByID(id);PrintWriter writer = null;String body = "";try {writer = response.getWriter();Scanner scanner = new Scanner(request.getInputStream());scanner.useDelimiter("\\A");body = scanner.hasNext() ? scanner.next() : "";scanner.close();} catch (Exception ex) {writer.write("get request.getInputStream error:" + ex.getMessage());return;}if (body.isEmpty()) {throw new GlobalException("ONLYOFFICE回调保存请求体未空");}JSONObject jsonObj = JSONObject.parseObject(body);int status = (Integer) jsonObj.get("status");int saved = 0;String key = jsonObj.get("key").toString();if (status == 2 || status == 3 || status == 6) //MustSave, Corrupted{String downloadUri = (String) jsonObj.get("url");System.out.println(downloadUri);try {String fileName = generateUniqueFileName(extractFileName(notemodeltypeenum.getContentStr()));String savePath = RuoYiConfig.getProfile()+"/"+fileName;downloadFile(downloadUri,savePath);// 更新原数据的文件地址String s = replacePathAfterProfile(notemodeltypeenum.getContentStr(), "/" + fileName);notemodeltypeenum.setContentStr(s);notemodeltypeenumService.updateNotemodeltypeenum(notemodeltypeenum);} catch (Exception ex) {saved = 1;ex.printStackTrace();}}writer.write("{\"error\":" + saved + "}");}public static void downloadFile(String fileUrl, String saveDir) {try {URL url = new URL(fileUrl);URLConnection connection = url.openConnection();// 5000 milliseconds is an example timeout valueconnection.setConnectTimeout(5000);connection.setReadTimeout(5000);try (BufferedInputStream in = new BufferedInputStream(connection.getInputStream());FileOutputStream fileOutputStream = new FileOutputStream(saveDir)) {byte[] dataBuffer = new byte[1024];int bytesRead;while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {fileOutputStream.write(dataBuffer, 0, bytesRead);}}System.out.println("File downloaded successfully: " + saveDir);} catch (IOException e) {System.out.println("Error downloading the file: " + e.getMessage());e.printStackTrace();}} // // public static void main(String[] args) { // downloadFile("https://dsgrcdnblobprod5u3.azureedge.net/catalog-assets/zh-cn/a32a147f-1f69-4fd5-8a39-c25b2a0093e8/tf67429532_wac-987650ec15fa.docx","D:/新建文件夹/87650ec15fa.docx"); // }public static String generateUniqueFileName(String originalFilename) {String fileExtension = ""; // 文件扩展名int i = originalFilename.lastIndexOf('.');if (i > 0) {fileExtension = originalFilename.substring(i);}return UUID.randomUUID().toString() + fileExtension; // 生成带有扩展名的唯一文件名}public static String extractFileName(String url) {// 检查url是否为空if (url == null || url.isEmpty()) {return "";}// 查找最后一个斜杠的位置int lastIndex = url.lastIndexOf('/');if (lastIndex == -1) {return ""; // 如果没有找到斜杠,返回空字符串}// 从最后一个斜杠之后的位置开始提取子字符串return url.substring(lastIndex + 1);}public static String replacePathAfterProfile(String url, String newPath) {if (url == null || url.isEmpty()) {return url; // 或抛出异常,取决于你的错误处理策略}// 找到"profile"后的第一个斜杠的索引int profileIndex = url.indexOf("/profile");if (profileIndex == -1) {return url; // 如果找不到"profile",返回原始URL}// 计算"profile"之后的部分开始的索引int startReplaceIndex = profileIndex + "/profile".length();// 构造新的URLreturn url.substring(0, startReplaceIndex) + newPath;}
参考文章:
onlyoffice+vue实现在线预览在线编辑_onlyoffice vue-CSDN博客
SpringBoot集成onlyoffice实现word文档编辑保存-阿里云开发者社区
相关文章:
vue+onlyOffice+java : 集成在线编辑word并保存
1.docker部署onlyOffice 1.1拉取最新版onlyOffice镜像 sudo docker pull onlyoffice/documentserver 1.2运行以下命令运行容器 其中 -v 后的第一部分是挂载自己的linux的哪个目录 # 启动docker容器,默认启动端口为80,可以进行修改 docker run -i -t …...

linux上用Jmter进行压测
在上一篇中安装好了Jmeter环境,在这一篇中将主要分享如何使用jmeter在linux中进行单机压测。 1.项目部署 在这里我们先简单部署一下测试环境,所用到的项目环境是个jar包,先在linux上home目录下新建app目录,然后通过rz命令将项目ja…...

【Java代码审计】代码审计的方法及常用工具
【Java代码审计】代码审计的方法及常用工具 代码审计的常用思路代码审计辅助工具代码编辑器测试工具反编译工具Java 代码静态扫描工具 代码审计的常用思路 1、接口排查(“正向追踪”):先找出从外部接口接收的参数,并跟踪其传递过…...

我国吻合器市场规模不断扩大 国产化率有所增长
我国吻合器市场规模不断扩大 国产化率有所增长 吻合器是替代手工切除或缝合的一种医疗器械,其工作原理与订书机十分相似,可利用钛钉对组织进行离断或吻合。经过多年发展,吻合器种类逐渐增多,根据手术方式不同,吻合器大…...

深度剖析Comate智能产品:科技巧思,实用至上
文章目录 Comate智能编码助手介绍Comate应用场景Comate语言与IDE支持 Comate安装步骤Comate智能编码使用体验代码推荐智能推荐生成单测注释解释注释生成智能问答 Comate实战演练总结 Comate智能编码助手介绍 市面上现在有很多智能代码助手,当时互联网头部大厂百度也…...

Centos 7.9 配置VNCServer实现远程vnc连接
文章目录 1、Centos安装图形界面1.1、安装X Windows System图形界面1.2、安装GNOME图形界面 2、VNC SERVER配置2.1、VNC SERVER安装2.2、VNC SERVER配置1)创建vnc配置文件2)修改配置文件内容3)完整配置文件参考 2.3、设置vnc密码2.4、配置防火…...
设计模式-08 - 模板方法模式 Template Method
设计模式-08 - 模板方法模式 Template Method 1.定义 模板方法模式是一种设计模式,它定义了一个操作的骨架,而由子类来决定如何实现该操作的某些步骤。它允许子类在不改变算法结构的情况下重定义算法的特定步骤。 模板方法模式适合用于以下情况&am…...
Android 适配阿拉伯语之vector图标镜像
Android 适配阿拉伯语之vector图标镜像 android:autoMirrored“true” 属性简单而直接的方法来自动处理 RTL 环境中图标的翻转。 使用 android:autoMirrored“true” 在 Vector Drawable 中是一种非常方便的方法,因为它允许你使用相同的 drawable 资源来适应不同的…...

推荐4个可用的github国内镜像
Github是全球最大的代码托管云平台,超过1亿用户在平台上分享代码及数据,深受生物信息学软件开发者的喜爱,并且现在发表文章,若涉及到代码,编辑还要求我们把代码及数据存放在github上,以便检查数据的真实性和…...

从项目开始学习Vue——02(若依框架)
往期: 从项目开始学习Vue——01 目录标题 一、基础插件(一)路由Vue Router(二)导航守卫(路由拦截器)二、Vuex(一)什么是VuexVuex的部分介绍内容: (…...

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(二)
DHTMLX Suite UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件,这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足项目管理应用…...

springboot整合redis多数据源(附带RedisUtil)
单数据源RedisUtil(静态) 单数据源RedisUtil,我这里implements ApplicationContextAware在setApplicationContext注入redisTemplate,工具类可以直接类RedisUtil.StringOps.get()使用 package com.vehicle.manager.core.util;import com.alibaba.fastjson.JSON; import lombok.e…...
Web实时通信的学习之旅:SSE(Server-Sent Events)的技术详解及简单示例演示
文章目录 一、什么是SSE二、SSE技术的基本原理三、SSE适用于场景四、Node服务端示例1、协议2、格式3、事件3.1、事件3.2、事件唯一标识符3.3、重连事件 4、具体示例 五、客户端示例1、检测客户端是否支持SSE2、创建客户端连接3、事件监听4、接收事件5、自定义事件6、错误处理7、…...

Apache Flume事务
Apache Flume 中的事务处理是指 Flume Agent 在处理事件流时的一种机制,用于确保数据的可靠传输和处理。 1. 事务概述: Flume 中的事务是指一组事件的传输和处理,这些事件在传输过程中要么全部成功完成,要么全部失败࿰…...

根据部门id删除该部门下的员工(事务)
application.properties: 或: application.yml: 新表: 日志对象类: 日志service类: 日志service接口: 日志mapper类: 部门service类: 员工mapper类:...
Java之String类
一、String类常用方法 1.引用类型的比较 我们知道在Java中两个引用遍历是不能用" "号来比较的,而String类重写了父类objects的equals方法, 实现了引用类型的比较 例子 import java.util.Scanner; public class Main { public static void…...
es终止快照恢复进程的方法
方法1、删除索引可以终止,恢复进程。 DELETE index_* // 按通配符删除以index_开头的索引 DELETE _all // 删除全部索引 POST *,-.*/_close 关闭索引 POST *,-.*/_open 打开索引 DELETE *,-.* 删除全部索引方法2、强制重启es 集群也可也终…...
ubantu安装rabbbitmq
ubantu安装rabbbitmq 安装Erlang1、在linux下直接安装2、上传Erlang文件后解压 安装rabbitmq开启web管理接口创建用户及修改guest密码,删除guest默认账号 安装Erlang 1、在linux下直接安装 #运行以下命令直接安装: sudo apt-get install erlang#可运行…...

了解 条码工具 Dynamsoft 在条码读取器中的形态运算
在图像处理中,术语形态学是指分析形状以填充小孔、去除噪声、提取轮廓等的一组操作。形态学操作很像空间卷积中的过滤过程。有两个部分在起作用:结构元素和预定义的计算规则。 点击下载Dynamsoft最新版https://www.evget.com/product/3691/download 结…...

NIO和NIO.2对比
Java NIO (New Input/Output) 是从Java 1.4版本开始引入的一个新的I/O API,用于替代原来的BIO(Blocking I/O)API。NIO提供了更加灵活和高效的网络通信方式,特别适合于高吞吐量的网络编程。NIO的主要特点是非阻塞模式,它…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...

Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...