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的主要特点是非阻塞模式,它…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
