金山WPS文档在线编辑

背景: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 = param1
    let div = document.createElement('div');

    div.setAttribute('id', param2); // 设置iframe的ID
    div.style.height = '520px'
// 将div添加到DOM中
    document.body.appendChild(div); // 添加到body的末尾
    const KSInstance = OpenSDK.config({
      url,
      mount: document.querySelector("#"+param2), // 挂载 iframe 节点
      commandBars: [
        {
          cmbId: 'HeaderMiddle', // 组件 ID
          attributes: {
            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.data
      switch (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.Range
      const start = await range.Start
      const 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.Application
      await app.ActiveDocument.SetReadOnly({
        Value: mode === 'preview'
      })
    }
 async function deleteEle(ceebElemPlaceHolder) {
      await KSInstance.ready();
      const app = KSInstance.Application
      app.ActiveDocument.ReplaceText([
        {
          key: ceebElemPlaceHolder,
          value: ''
        }
      ])
    }

  };
</script>
</html>

文档地址

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

javascript 复制代码
 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通信操作文档内容:

javascript 复制代码
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);
相关推荐
运筹vivo@1 分钟前
攻防世界:Web_php_include
前端·web安全·php
夏之小星星14 分钟前
el-table实现跨页全选
javascript·vue.js
囊中之锥.14 分钟前
从分词到词云:基于 TF-IDF 的中文关键词提取实践
前端·tf-idf·easyui
小二·16 分钟前
Python Web 开发进阶实战:生物启发计算 —— 在 Flask + Vue 中实现蚁群优化与人工免疫系统
前端·python·flask
局外人LZ16 分钟前
Forge:web端与 Node.js 安全开发中的加密与网络通信工具集,支持哈希、对称 / 非对称加密及 TLS 实现
前端·安全·node.js
2301_8187320617 分钟前
前端一直获取不到后端的值,和数据库字段设置有关 Oracle
前端·数据库·sql·oracle
vx_bisheyuange17 分钟前
基于SpringBoot的酒店管理系统
前端·javascript·vue.js·spring boot·毕业设计
慧一居士21 分钟前
同一个服务器上不同的域名跳往不同的前端项目页面,不显示端口号 ngnix根据不同域名跳转
运维·服务器·前端
派大鑫wink21 分钟前
【Day38】Spring 框架入门:IOC 容器与 DI 依赖注入
java·开发语言·html
ct97823 分钟前
WebGL核心API
前端·gis·webgl