金山WPS文档在线编辑

news/2024/12/5 18:58:21/
htmledit_views">

背景:vue项目,同一个页面存在多个编辑器场景。

按照往常一样,将编辑器封装成组件然后在页面引入,只能显示最后渲染的一个编辑器,前面渲染的都会消失。尝试过直接用iframe指向文档地址,不用金山提供的jdk还是有一样的问题。

下面是金山的开发给的解决方案:

​​

 以下是我根据自己的情况实现的:这个html和需要用到的jdk放在public文件夹中

html">// KSIframe.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>www</title>
</head>
<body>
</body>
<script src="./open-jssdk-v0.0.13.umd.js"></script>
<script>window.onload = () => {const params = new URLSearchParams(window.location.search);console.log(params.get('url'), 'url')// console.log(params.get('editorId'), 'editorId')// console.log(params.get('isShowTopArea'), 'isShowTopArea')// console.log(params.get('isShowHeader'), 'isShowHeader')// console.log(params.get('isEditable'), 'isEditable')const param1 = params.get('url')const param2 = params.get('editorId')const isEdit = params.get('isEditable') === 'true';const isShowTopArea = params.get('isShowTopArea') === 'true';const isShowHeader = params.get('isShowHeader') === 'true';const url = param1let div = document.createElement('div');div.setAttribute('id', param2); // 设置iframe的IDdiv.style.height = '520px'
// 将div添加到DOM中document.body.appendChild(div); // 添加到body的末尾const KSInstance = OpenSDK.config({url,mount: document.querySelector("#"+param2), // 挂载 iframe 节点commandBars: [{cmbId: 'HeaderMiddle', // 组件 IDattributes: {enable: isEdit, // 禁用组件(组件显示但不响应点击事件)},},],wordOptions: {enableReadOnlyComment: isEdit,isBestScale: false, // 打开文档时,默认以最佳比例显示},commonOptions: {isShowTopArea, // 隐藏顶部区域(头部和工具栏)isShowHeader, // 隐藏头部区域// isBrowserViewFullscreen: false, // 是否在浏览器区域全屏// isIframeViewFullscreen: false, // 是否在 iframe 区域内全屏// acceptVisualViewportResizeEvent: true, // 控制 WebOffice 是否接受外部的 VisualViewport},});window.addEventListener('message', function(event) {// console.log(event.origin, '------>', window.location.origin);if (event.origin !== window.location.origin) {return; // 只接受来自特定源的消息}// console.log('Received message:', event.data);let getData = event.dataswitch (getData.type) {case 'insertEle':insertEle(getData.content, getData.markName)break;case 'setMode':setMode(getData.mode);break;case 'deleteEle':deleteEle(getData.key);break;default:console.log('没这个方法')}// 可以回复消息// event.source.postMessage('Hi there!', event.origin);}, false);async function insertEle(content, markName) {await KSInstance.ready();const selection = await KSInstance.Application.ActiveDocument.ActiveWindow.Selection// 区域对象const range = await selection.Rangeconst start = await range.Startconst end = start + content.length// 在选区后面插入内容await selection.InsertAfter(content)// const end = await range.End// console.log(range, 'range')// console.log(start, 'start1')// console.log(end, 'end1')await KSInstance.Application.ActiveDocument.Bookmarks.Add({Name: markName,Range: {Start: start,End: end}})const marks1 = await KSInstance.Application.ActiveDocument.Bookmarks.Json()}async function setMode(mode){await KSInstance.ready();const app = KSInstance.Applicationawait app.ActiveDocument.SetReadOnly({Value: mode === 'preview'})}async function deleteEle(ceebElemPlaceHolder) {await KSInstance.ready();const app = KSInstance.Applicationapp.ActiveDocument.ReplaceText([{key: ceebElemPlaceHolder,value: ''}])}};
</script>
</html>

文档地址

等初始化需要用到的参数,放在父页面iframe的src中,通过路由参数传递。其它对文档的操作,用iframe通信的方式实现。

 let urlEncoded = encodeURIComponent(fileUrl),src = `/KSIframe.html?url=${urlEncoded}&editorId=${this.editorId}&isShowTopArea=${this.isShowTopArea}&isShowHeader=${this.isShowHeader}&isEditable=${this.isEditableFile}`this.$nextTick(()=>{let box = document.getElementById(this.editorBoxId) // 插入iframe的父元素// 移除所有子元素box.replaceChildren();let iframe = document.createElement('iframe')iframe.setAttribute('src', src)iframe.setAttribute('id', this.editorIframeId)iframe.style.height = '500px'iframe.style.width = '100%'function handleLoaded(){let postData = {type: 'setMode',mode: isPreview ? 'preview' : 'edit'}iframe.contentWindow.postMessage(postData, window.location.origin);this.removeEventListener('load', handleLoaded, false);}iframe.addEventListener('load', handleLoaded, false);box.appendChild(iframe)})

iframe通信操作文档内容:

let iframe = document.getElementById(this.editorIframeId)
let postData = {type: 'deleteEle',key: yourKey
}
iframe.contentWindow.postMessage(postData, window.location.origin);let iframe = document.getElementById(this.editorIframeId)
let postData = {type: 'insertEle',content,markName,
}
iframe.contentWindow.postMessage(postData, window.location.origin);


http://www.ppmy.cn/news/1543763.html

相关文章

metasploit/modules/evasion 有哪些模块,以及具体使用案例

Metasploit框架的evasion模块用于生成绕过安全检测的有效载荷。以下是一些常见的evasion模块及其使用案例&#xff1a; 1. 通用Evasion模块 windows/meterpreter/reverse_tcp_rc4&#xff1a;使用RC4加密的反向TCP Meterpreter会话。 set PAYLOAD windows/meterpreter/reverse…

[QUIC] Packets 和 Frames 概述

Packets 和 Frames 概述 受保护的数据包 (Protected Packets) 基于不同的包类型, QUIC 使用不同等级的保护机制. Version Negotoation 包不受保护. Retry 包使用 AEAD 进行保护。 Initial 包使用 AEAD 进行保护, 但是使用的 Key 是由一个网络可见的值计算出来的。 因此 Ini…

无需手动部署的正式版comfyUI是否就此收费?开源等同免费?

​ ​ 关于ComfyUI的正式版是否会收费的问题是很多AI玩家都关心的问题。 一旦ComfyUI正式版发布&#xff0c;我们是否需要为它买单&#xff1f;不再开源 同时这也引出了一个核心问题&#xff1a;开源究竟等不等于免费&#xff1f; ComfyUI正式版到底是什么&#xff1f;它会收…

IO流--13--RandomAccessFile

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 RandomAccessFile1.简介2.RandomAccessFile的作用有哪些&#xff1f;3.RandomAccessFile类有两个构造器&#xff1a;3.常用API介绍 RandomAccessFile 案例环境搭建1…

计算机网络:网络层 —— IP数据报的发送和转发过程

文章目录 IP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报示例 IP数据报的发送和转发过程 IP 数据报的发送和转发过程包含以下两个过程&#xff1a; 主机发送IP数据报路由器转发IP数据报 直接交付&#xff1a;源主机与目的主机在同一网络中间接交付&#xff1a;…

奇瑞不客气智驾 晚不晚?

文/孔文清 一直很好奇&#xff1a; 尹同跃董事长的金句“智驾不客气”&#xff0c;应该怎么翻译成英语&#xff1f; 谷俊丽的演讲PPT给了我答案&#xff1a; All in Ai Cars ——全力以赴、全情投入智能化汽车。 谷俊丽是奇瑞全球创新大会上最兴奋的人之一&#xff0c;有一种闭…

Flink CDC系列之:学习理解核心概念——Data Sink

Flink CDC系列之&#xff1a;学习理解核心概念——Data Sink sink参数示例 sink 数据接收器用于应用架构更改并将更改数据写入外部系统。 数据接收器可以同时写入多个表。 参数 为了描述数据接收器&#xff0c;需要以下内容&#xff1a; 参数含义可选/必需typesink的类型&…

【计算机网络】零碎知识点(易忘 / 易错)总结回顾

一、计算机网络的发展背景 1、网络的定义 网络是指将多个计算机或设备通过通信线路、传输协议和网络设备连接起来&#xff0c;形成一个相互通信和共享资源的系统。 2、局域网 LAN 相对于广域网 WAN 而言&#xff0c;局域网 LAN 主要是指在相对较小的范围内的计算机互联网络 …