基于vue-onlyoffice实现企业office web在线应用

news2025/4/6 6:27:04

目录

1.背景... 1

2.Onlyoffice介绍... 2

3.Onlyoffice核心api介绍... 2

3.1 ApiDocument 2

3.2 ApiParagraph. 2

3.3 ApiTable. 2

3.4. ApiRange. 3

4.Onlyoffice插件介绍... 3

4.1 插件定义... 3

4.2 插件对象... 3

4.3 插件结构... 4

4.4 插件内嵌使用方式... 4

4.5 插件外挂使用方式... 5

5.集成方案介绍... 6

5.1 开发vue-onlyoffice文档组件... 6

5.2 基于插件实现文档切换和段落/表格内容选中... 8

6.集成问题分享... 9

6.1如何隐藏插件... 9

6.2避免onlyoffice跨域... 10

7.参考链接... 10

1.背景

基于文档审核项目,需要对审核的结果在office word里面进行高亮,并能自动跳转到指定页的对应文字处,基于这样的需求背景下,通过vue进行onlyoffice文档方案集成。

2.Onlyoffice介绍

3.Onlyoffice核心api介绍

3.1 ApiDocument

英文名称

中文说明

AddComment

添加批注

AddElement

添加文档元素(:元素常见类型Paragraph\Table)

GetAllParagraphs

获取所有段落

GetAllTables

获取所有表格

GetElement

获取文档元素

GetCommentById

获取批注

GetPageCount

获取页数

GetRange

根据字坐标获取对应文档部分

Search

根据文字内容获取对应文档部分

3.2 ApiParagraph

英文名称

中文说明

AddText

添加段落文本

AddElement

添加段落要素

AddPageBreak

添加分页符

GetElement

获取段落元素

GetText

获取段落文本

GetRange

根据字坐标获取对应段落部分

Search

根据文字内容获取对应段落部分

Select

段落文本选中

SetBold

设置段落文本字体粗细

3.3 ApiTable

英文名称

中文说明

AddColumn

添加表格列

AddRow

添加表格行

AddElement

添加表格元素

GetElement

获取段落元素

GetText

获取段落文本

GetRange

根据字坐标获取对应表格部分

Search

根据文字内容获取对应表格部分

GetColumn

获取表格列

GetRow

获取表格行

Select

选中指定单元格

3.4. ApiRange

英文名称

中文说明

AddComment

指定位置添加批注

AddText

指定位置添加文本

GetParagraph

获取指定位置段落

GetRange

根据字坐标获取对应部分

GetText

获取指定位置文本

GetRange

根据字坐标获取对应表格部分

Select

选中指定位置内容

SetHighlight

高亮指定位置内容

SetPosition

截取指定位置内容

4.Onlyoffice插件介绍

4.1 插件定义

ONLYOFFICE offer support for plugins allowing developers to add specific features to the editors that are not directly related to the OOXML format.

4.2 插件对象

Asc 对象

用于操作onlyoffice文档的对象

Asc.plugin对象

任何插件都有window.Asc.plugin对象,该对象又具有几种方法,用于与ONLYOFFICE文档、电子表格和演示文稿编辑器进行交互

方法名称

方法作用

callCommand

定义用于将数据发送回编辑器的方法。它允许插件发送结构化数据,这些数据可以插入到生成的文档文件中(格式化的段落、表格、文本部分和单独的单词等)

executeMethod

定义使用插件执行某些编辑器方法的方法

Asc.scope对象

用于将任何附加数据(对象、参数、变量等)传递给 window.Asc.plugin.callCommand 方法,该方法在其独立的上下文中执行

4.3 插件结构

Develop a plugin. Follow the plugin structure described here. The plugin folder must contain three files required for the plugin to work: config.jsonindex.htmlpluginCode.js.

4.4 插件内嵌使用方式

参考4.3方式自定义插件页面,即需按规范编写相关html、js逻辑,此时插件页面和onlyoffice展示页面会绑定在一起,如下图如下:

此时可以直接在js文件操作插件对象Asc

4.5 插件外挂使用方式

参考4.3方式自定义插件页面,此时赋予一个默认的index.html,js相关逻辑不用处理,通过这样处理,隐藏内嵌插件页面的同时,获取onlyoffice的插件对象Asc,从而可以独立于onlyoffice之外,用vue编写操作页面的逻辑,相对于4.4方式更灵活,并支持多文档切换,如下图所示:

#待分享(即通过外挂右侧操作页面,控制左侧word页面的元素)

由于此时不依赖js文件操作插件对象Asc,此时需要通过iframe机制即window对象,间接获取Asc对象,onlyoffice iframe视图如下:

此时获取获取Asc对象方法为

document.getElementsByTagName("iframe")[0]. .contentWindow[0].Asc

5.集成方案介绍

5.1 开发vue-onlyoffice文档组件

代码示例1:

<!-- word展示 -->

         <view-word

          v-if="docType === 'word'"

          :editorConfig="viewWordCfg"

            ref="onlyofficeEditor"

代码示例2:

<template>

  <div id="officeWord"></div>

</template>

<script>

import loadScript from "@/utils/loadScript";

// import "../js/api.js";

export default {

  name: "onlyofficeEditor",

  props: ["editorConfig"],

  mounted() {

    // 文档服务地址,依据环境更改

    const docApiUrl = `/office/web-apps/apps/api/documents/api.js`;

    loadScript(docApiUrl, "onlyoffice-api-script")

      .then(() => this.onLoad())

      .catch(() => {

        this.onError(-2);

      });

    // Promise.all([this.onLoad()]).catch(() => {

    //   this.onError(-2);

    // });

    // this.onReady();

  },

  beforeDestroy() {

    const id = "officeWord";

    if (window?.DocEditor?.instances[id]) {

      window.DocEditor.instances[id].destroyEditor();

      window.DocEditor.instances[id] = undefined;

    }

  },

  methods: {

    onLoad() {

      try {

        const id = "officeWord";

        if (!window.DocsAPI) this.onError(-3);

        if (window?.DocEditor?.instances[id]) {

          console.log("Skip loading. Instance already exists", id);

          return;

        }

        if (!window?.DocEditor?.instances) {

          window.DocEditor = { instances: {} };

        }

        const editor = window.DocsAPI.DocEditor(

          id,

          Object.assign(

            {

              events: {

                onAppReady: this.onAppReady,

              },

            },

            this.editorConfig

          )

        );

        window.DocEditor.instances[id] = editor;

      } catch (err) {

        console.error(err);

        this.onError(-1);

      }

    },

    onAppReady() {

      const id = "officeWord";

      window.DocEditor.instances[id];

    },

    onError(errorCode) {

      let message;

      switch (errorCode) {

        case -2:

          message = "Error load DocsAPI from " + this.documentServerUrl;

          break;

        case -3:

          message = "DocsAPI is not defined";

          break;

        default:

          message = "Unknown error loading component";

          errorCode = -1;

      }

      if (typeof this.onLoadComponentError == "undefined") {

        console.error(message);

      } else {

        this.onLoadComponentError(errorCode, message);

      }

    },

  },

};

</script>

<style scoped></style>

5.2 基于插件实现文档切换和段落/表格内容选中

const oIframe = document.getElementsByTagName("iframe")[0];

        if (!oIframe) {

          return;

        }

        let Asc = oIframe.contentWindow[0].Asc;

        const { tableId, startIndex, endIndex } = ele;

        Asc.scope.start = startIndex;

        Asc.scope.end = endIndex;

        Asc.scope.tableId = tableId;

        sessionStorage.setItem("ascScope-word", JSON.stringify(Asc.scope));

        console.log(Asc);

        // this.viewWordCfg

        Asc.plugin.callCommand(

          function () {

            // eslint-disable-next-line no-undef

            var oDocument = Api.GetDocument();

            var ascScope = JSON.parse(sessionStorage.getItem("ascScope-word"));

            var start_index = ascScope ? Number(ascScope.start) : 0;

            var end_index = ascScope ? Number(ascScope.end) : 0;

            var oTableArr = [];

            for (var i = 0; i < oDocument.GetElementsCount(); i++) {

              var oElement = oDocument.GetElement(i);

              var sClassType = oElement.GetClassType();

              if (sClassType == "table") {

                oTableArr.push(oElement);

              }

            }

            // 区分表格还是文字 进行提示

            //

            if (ascScope && ascScope.tableId !== null) {

              // 表格

              var oTable = oTableArr[0];

              //表格是按字数来的,不包括空格

              var oTableRange = oTable.GetRange(start_index, end_index);

              oTableRange.SetHighlight(20, 37, 220);

              oTableRange.Select();

            } else {

              // 文字

              var oRange = oDocument.GetRange(start_index, end_index);

              oRange.SetHighlight(20, 37, 220);

              oRange.Select();

            }

          },

          false,

          true

        );

6.集成问题分享

6.1如何隐藏插件

需修改插件目录下的config.json文件,即配置isVisual 为false 实现插件隐藏

6.2避免onlyoffice跨域

由于涉及iframe操作和第三方服务,需保证onlyoffice服务和前端服务在同一个nginx下,从而避免跨域

7.参考链接

文档相关: https://api.onlyoffice.com/docbuilder/basic

插件相关:https://api.onlyoffice.com/plugin/basic

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Echarts 柱状图实现同时显示百分比+原始值+汇总值

原始效果&#xff1a;柱状图 二开效果&#xff1a; 核心逻辑 同时显示百分比和原始值 label: {show: true,position: inside,formatter: (params) > {const rawValue rawData[params.seriesIndex][params.dataIndex];const percentage Math.round(params.value * 1000) / …

基于springboot+vue+uniapp的校园二手交易小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

达梦数据库基础操作-查询

一、基础查询 1 &#xff09;单表查询 1. 查看表结构 使用两种方式可查看数据库的表结构&#xff1a; 查询后会显示该表的创建语句以及结构 2. 查询全表 使用 SELECT * 查询全表&#xff0c;此时数据库会返回表所有列 3. 行过滤 使用条件查询进行过滤&#xff0c;…

2024电赛H题参考方案(+视频演示+核心控制代码)——自动行使小车

目录 一、题目要求 二、参考资源获取 三、参考方案 1、环境搭建及工程移植 2、相关模块的移植 4、整体控制方案视频演示 5、视频演示部分核心代码 总结 一、题目要求 小编自认为&#xff1a;此次H题属于控制类题目&#xff0c;相较于往年较为简单&#xff0c;功能也算单一&…

Vue - CSS基础学习

一、元素及属性 CSS 是为 web 内容添加样式的代码。 style标签 1.语法 1.除了选择器部分&#xff0c;每个规则集都应该包含在成对的大括号里&#xff08;{}&#xff09;。 2.在每个声明里要用冒号&#xff08;:&#xff09;将属性与属性值分隔开。 3.在每个规则集里要用分号…

Windows执行jar包

配置环境变量&#xff1a; 命令行测试&#xff1a; java -version 将jar包上传至指定目录&#xff0c;在该目录下创建运行脚本&#xff1a; chcp 65001 java -Dfile.encodingutf-8 -jar jxpaddle-admin.jar chcp 65001&#xff1a;将当前cmd编码改为UTF-8&#xff0c;仅对当…

单片机芯片程序读取方法和工具

如何把单片机芯片程序读取出来 读取芯片中的程序可以通过多种方法实现&#xff0c;具体方法取决于芯片的类型和可用的工具。 一、使用‌Keil软件&#xff1a; 如果芯片是Flash类型的&#xff0c;可以使用Keil软件配合硬件调试工具进行读取。首先&#xff0c;需要配置Keil工程&…

【Unity源码】多人FPS游戏

项目概述 《多人FPS游戏》(Multiplayer-FPS) 是一个基于Unity3D引擎开发的多人第一人称射击游戏。该项目支持多种输入设备&#xff0c;包括Kinect、Xbox控制器、Leap Motion手势控制、VR眼镜等&#xff0c;提供了丰富的交互体验。 项目特点 多种输入设备支持&#xff1a;除了…

基于北京市空气质量影响因素研究系统【城市可换爬虫获取、LSTM、Flask、Echarts、MySQL、TensorFlow】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主研究背景国内外研究现状研究目的研究意义关键技术理论介绍数据采集数据分析与大屏设计大屏相关性分析LSTM模型训练系统集成展示总结每文一语 有需要本项目的代码或文档以及全部资源&#xf…

springboot高校实验室安全管理系统-计算机毕业设计源码73839

目 录 摘要 1 绪论 1.1 研究背景 1.2 选题意义 1.3研究方案 1.4论文章节安排 2相关技术介绍 2.1 B/S结构 2.2 Spring Boot框架 2.3 Java语言 2.4 MySQL数据库 3系统分析 3.1 可行性分析 3.2 系统功能性分析 3.3.非功能性分析 3.4 系统用例分析 3.5系统流程分析…

双指针专题

前言(回顾一下)&#xff1a; Leetcode 283.移动零 思路&#xff1a; 使用双指针&#xff0c;左指针指向当前已经处理好的序列的尾部&#xff0c;右指针指向待处理序列的头部。右指针不断向右移动&#xff0c;每次右指针指向非零数&#xff0c;则将左右指针对应的数交换&#xf…

C语言 -- 动态内存管理

C语言 -- 动态内存管理 1. 为什么要有动态内存分配2. malloc 和 free2.1 malloc2.2 free 3. calloc 和 realloc3.1 calloc3.2 realloc 4. 常见的动态内存的错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对非动态开辟内存使用free释放4.4 使用free释放一块动…

嵌入式学习——C语言指针(一)

一、地址和指针的概念 地址&#xff1a;内存单元的编号。 指针&#xff1a;一个变量的首地址就叫做该变量的指针。 1、内存中存取数据的方式 1&#xff09;直接存取 直接用变量名存取变量所占内存单元的内容 例&#xff1a; int y,x 3; y 3*x2; 2&#…

【日记】今天又是哪朵小云不开心了呀(1886 字)

正文 上午上班没多久&#xff0c;天就特别阴&#xff0c;感觉像是要下暴雨的样子。前台接了一个电话&#xff0c;家里人打来的&#xff0c;她妈妈叮嘱她&#xff0c;要注意一点。他们那边已经开始下了。她转过头对我笑笑说&#xff0c;原来下雨在一个城里也能不同步。 当时我笑…

AttributeError: ‘NoneType‘ object has no attribute ‘shape‘

AttributeError: ‘NoneType‘ object has no attribute ‘shape‘ 目录 AttributeError: ‘NoneType‘ object has no attribute ‘shape‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰…

多家隧道代理价格:阿布云、快代理、小象代理、熊猫代理和亿牛云……

随着奥运的热度攀升&#xff0c;各大品牌也在抓紧时机赶上这波奥运热潮&#xff0c;随之而来的大量数据信息收集和分析工作也接踵而至&#xff0c;在这一数据采集过程中&#xff0c;HTTP代理的质量和价格对企业的效率和成本调控重要性不言而喻。我们大部分人在日常购买产品的时…

2235234234

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年6月20日 最后&#xff1a; 十分感谢你可以耐着性子把它读完和我可以坚持写到这里&#xff0c;送几句话&#xff0c;对你&#xff0c;也对我&#xff1a; 1.一个冷知识&#xff1a; …

细说MCU的DAC1实现两个通道同时输出的方法

目录 一、参考硬件 二、 建立新工程 1.配置DAC 2.配置DMA 3.配置定时器 4.配置时钟和Debug 三、修改代码 1.初始化定时器和DAC 2.定义波形数据 3.波形数据的产生方法 四、查看结果 一、参考硬件 本项目依赖的软件和硬件工程参考本文作者写的文章&#xff1a; 细说MC…

手写RPC框架,与Spring整合,基于Netty作为网络框架,protobuf作为序列化协议。可以和实际项目相结合完美运行

注&#xff1a;由于RPC框架过于庞大所以本篇文章只是作为阅读RPC源码的一个指导&#xff0c;设计精巧之处还需要各位读者结合源码进行实践 RPC源码地址&#xff1a;https://github.com/xhpcd/rpc git clone: https://github.com/xhpcd/rpc.git 如果觉得有收获麻烦留下一颗st…

使用 Easysearch 打造企业内部知识问答系统

大家可能都有这样的经历&#xff0c;刚入职一家企业时&#xff0c;同事往往会给你分享一些文档资料&#xff0c;有可能是产品信息、规章制度等等。这些文档有的过于冗长&#xff0c;很难第一时间找到想要的内容。有的已经有了新版本&#xff0c;但员工使用的还是老版本。 基于…