当前位置: 首页 > news >正文

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容器&#xff0c;默认启动端口为80&#xff0c;可以进行修改 docker run -i -t …...

linux上用Jmter进行压测

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

【Java代码审计】代码审计的方法及常用工具

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

我国吻合器市场规模不断扩大 国产化率有所增长

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

深度剖析Comate智能产品:科技巧思,实用至上

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

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&#xff09;创建vnc配置文件2&#xff09;修改配置文件内容3&#xff09;完整配置文件参考 2.3、设置vnc密码2.4、配置防火…...

设计模式-08 - 模板方法模式 Template Method

设计模式-08 - 模板方法模式 Template Method 1.定义 模板方法模式是一种设计模式&#xff0c;它定义了一个操作的骨架&#xff0c;而由子类来决定如何实现该操作的某些步骤。它允许子类在不改变算法结构的情况下重定义算法的特定步骤。 模板方法模式适合用于以下情况&am…...

Android 适配阿拉伯语之vector图标镜像

Android 适配阿拉伯语之vector图标镜像 android:autoMirrored“true” 属性简单而直接的方法来自动处理 RTL 环境中图标的翻转。 使用 android:autoMirrored“true” 在 Vector Drawable 中是一种非常方便的方法&#xff0c;因为它允许你使用相同的 drawable 资源来适应不同的…...

推荐4个可用的github国内镜像

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

从项目开始学习Vue——02(若依框架)

往期&#xff1a; 从项目开始学习Vue——01 目录标题 一、基础插件&#xff08;一&#xff09;路由Vue Router&#xff08;二&#xff09;导航守卫&#xff08;路由拦截器&#xff09;二、Vuex&#xff08;一&#xff09;什么是VuexVuex的部分介绍内容&#xff1a; &#xff08…...

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(二)

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

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 在处理事件流时的一种机制&#xff0c;用于确保数据的可靠传输和处理。 1. 事务概述&#xff1a; Flume 中的事务是指一组事件的传输和处理&#xff0c;这些事件在传输过程中要么全部成功完成&#xff0c;要么全部失败&#xff0…...

根据部门id删除该部门下的员工(事务)

application.properties&#xff1a; 或&#xff1a; application.yml&#xff1a; 新表&#xff1a; 日志对象类&#xff1a; 日志service类&#xff1a; 日志service接口&#xff1a; 日志mapper类&#xff1a; 部门service类&#xff1a; 员工mapper类&#xff1a;...

Java之String类

一、String类常用方法 1.引用类型的比较 我们知道在Java中两个引用遍历是不能用" "号来比较的&#xff0c;而String类重写了父类objects的equals方法&#xff0c; 实现了引用类型的比较 例子 import java.util.Scanner; public class Main { public static void…...

es终止快照恢复进程的方法

方法1、删除索引可以终止&#xff0c;恢复进程。 DELETE index_* // 按通配符删除以index_开头的索引 DELETE _all // 删除全部索引 POST *,-.*/_close 关闭索引 POST *,-.*/_open 打开索引 DELETE *,-.* 删除全部索引方法2、强制重启es 集群也可也终…...

ubantu安装rabbbitmq

ubantu安装rabbbitmq 安装Erlang1、在linux下直接安装2、上传Erlang文件后解压 安装rabbitmq开启web管理接口创建用户及修改guest密码&#xff0c;删除guest默认账号 安装Erlang 1、在linux下直接安装 #运行以下命令直接安装&#xff1a; sudo apt-get install erlang#可运行…...

了解 条码工具 Dynamsoft 在条码读取器中的形态运算

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

NIO和NIO.2对比

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

Google准备好了吗?OpenAI发布ChatGPT驱动搜索引擎|TodayAI

在科技界波澜壮阔的发展中&#xff0c;OpenAI正式宣布其最新突破——一个全新的基于ChatGPT技术的搜索引擎&#xff0c;旨在直接挑战谷歌在搜索领域的统治地位。这一创新将可能彻底改变用户上网搜索的方式。 据悉&#xff0c;这款AI驱动的搜索引擎利用了ChatGPT的强大功能&…...

乐观锁、悲观锁、互斥锁、读写锁

乐观锁和悲观锁是两种不同的锁机制&#xff0c;用于在多线程环境下解决资源竞争问题。互斥锁和读写锁是两种常见的锁类型&#xff0c;它们都可以用来实现乐观锁或悲观锁。 乐观锁 是一种无锁机制&#xff0c;它假设在多线程环境下对共享资源的操作不会发生冲突&#xff0c;因…...

Gin入门指南:从零开始快速掌握Go Web框架Gin

官网:https://gin-gonic.com/ GitHub:https://github.com/gin-gonic 了解 Gin Gin 是一个使用 Go 语言开发的 Web 框架,它非常轻量级且具有高性能。Gin 提供了快速构建 Web 应用程序所需的基本功能和丰富的中间件支持。 以下是 Gin 框架的一些特点和功能: 快速而高效:…...

Scala里的class、object、case class、case object 、trait

Class&#xff08;类&#xff09; 定义和作用 Scala 中的 class 是一种蓝图&#xff0c;用于创建对象&#xff08;实例&#xff09;。它定义了对象的状态和行为。类可以包含字段&#xff08;属性&#xff09;和方法&#xff08;函数&#xff09;。类可以有构造器&#xff0c;…...

移动端自动化测试工具 Appium 之 main 启动

文章目录 一、背景二、生成xml文件2.1、创建xml方法2.2、执行主类MainTest2.3、自动生成的xml2.4、工程目录2.5、执行结果 三、命令行执行appium服务四、主方法启动类五、集成Jenkins六、总结 一、背景 Jenkins 做集成测试是不错的工具&#xff0c;那么UI自动化是否可以&#…...

WT32-ETH01作为TCP Client进行通讯

目录 模块简介WT32-ETH01作为TCP Client设置电脑作为TCP Server设置连接并进行通讯总结 模块简介 WT32-ETH01网关主要功能特点: 采用双核Xtensa⑧32-bit LX6 MCU.集成SPI flash 32Mbit\ SRAM 520KB 支持TCP Server. TCP Client, UDP Server. UDP Client工作模式 支持串口、wif…...

jni 返回二维byte数组

在JNI中返回二维byte数组&#xff0c;你需要在Java中准备一个相应的二维数组来接收这个返回值。在JNI层面&#xff0c;你可以创建一个二维的byte数组&#xff0c;并使用GetByteArrayRegion和SetByteArrayRegion来操作它。 以下是一个简单的例子&#xff1a; public class Jni…...

“webpack-dev-server --config build/webpack.dev.conf.js” 请问这个问题要如何修复

解决方案 修改部署方式&#xff1a; 使用 webpack 来打包你的项目&#xff0c;生成静态文件。在生产环境中&#xff0c;使用 Nginx 或其他 HTTP 服务器来提供服务&#xff0c;而不是使用 webpack-dev-server。 Dockerfile 调整&#xff1a; 确保 Dockerfile 中使用的命令是用于…...

TOOL使用fiddler导出的har文件导入到postman测试接口

在fiddler操作 export → File → Export Sessions → alls-->http arch v1.1 导出的har文件直接拖入到浏览器的调试工具中&#xff0c; 然后复制为curl&#xff0c;导入到postman中即可&#xff01;...

第十三届蓝桥杯决赛(国赛)真题 Java A 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 火柴棒数字试题 B: 小蓝与钥匙试题 C: 内存空间试题 D: 斐波那契数组试题 E: 交通信号试题 F: 数组个数试题 G: 六六大顺试题 H : \mathrm{H}: H: 选素数试题 I: 图书借阅试题 J \mathrm{J} J : 括号序列树 发现宝藏 前些天发现了一个…...