Vue3项目实现WPS文件预览和内容回填功能

news2025/6/9 23:49:26

技术方案背景:根据项目需要,要实现在线查看、在线编辑文档,并且进行内容的快速回填,根据这一项目背景,最终采用WPS的API来实现,接下来我们一起来实现项目功能。

1.首先需要先准备好测试使用的文档,并且做好标签节点的标记,在要需要回填的地地方打好标记标签

打开文档 => 点击菜单栏插入 => 找到要添加书签的地方,选择工具栏的书签按钮

输入对应的命名书签

表格书签是打标记在表格内容上方,便于查找表格位置方便替换;

2. 引入WPS Web Office SDK代码示例(vue项目举例,在根目录下的index.html文件中引入)

<script src="/wps-sdk/web-office-sdk-solution-v2.0.7.umd.js"></script>

注意事项

SDK路径需要根据实际存放位置调整,若使用CDN方式可替换为完整URL

当前示例使用的是v2.0.7版本的UMD格式SDK,适用于大多数浏览器环境

建议将脚本放在<head>标签内或<body>标签末尾,避免阻塞页面渲染

初始化示例

const config = {
  mount: document.getElementById('office-container'),
  url: 'https://example.com/test.docx'
};
WebOfficeSDK.initialize(config);

版本选择建议

生产环境建议锁定具体版本号(如示例中的v2.0.7)

测试环境可使用最新版本,但需注意API兼容性

UMD格式适用于传统网页开发,若使用模块化开发可考虑ES模块版本

以上代码需配合WPS官方文档使用,确保初始化参数配置正确(WPS官方文档:快速上手 | WPS WebOffice 开放平台)

3.使用HTML代码块编写的WPS文档在线查看容器代码:

 <!-- 创建wps文档在线查看容器 -->
<div id="wps-frame" class="w-full h-[calc(100%-60px)] bg-#eee custom-mount"></div>

代码说明

该代码创建了一个具有以下特性的div容器:

  • 使用id="wps-frame"作为唯一标识
  • 通过class属性应用了多个样式:
    • w-full:宽度100%
    • h-[calc(100%-60px)]:高度为总高度减去60px
    • bg-#eee:背景色设置为浅灰色
    • custom-mount:预留的自定义挂载类名

样式补充建议

如需更精确控制样式,可以添加CSS:

#wps-frame {
  border: 1px solid #ddd;
  margin: 0 auto;
  overflow: hidden;
}

4. 初始化WPS容器

const init = async () => {
  window.fileurlType = props.fileObj.fileurl.split('.').pop().toLowerCase();
  instance = WebOfficeSDK.init({
    //文档类型
    officeType: window.fileurlType === 'xlsx' || window.fileurlType === 'xls' 
      ? WebOfficeSDK.OfficeType.Spreadsheet 
      : window.fileurlType === 'docx' || window.fileurlType === 'doc' 
        ? WebOfficeSDK.OfficeType.Writer 
        : WebOfficeSDK.OfficeType.Otl,
    appId: "你申请的预览服务的appid",
    fileId: props.fileObj.fileid,
    token: token,
    mount: document.getElementById('wps-frame'),
    mode: props.submitType === true ? 'nomal' : 'simple',
  });
 //如果props.submitType为true,则设置为可以编辑 否则设置为只读
  if (props.submitType == false) {
    await instance.ready();
    const app = instance.Application;
    await app.ActiveDocument.SetReadOnly({
      Value: true
    });
  } else {
    await instance.ready();
    //根据接口返回信息对文档进行回填
    getInformationBackfilling();
  }
}

5. 容器初始化后我们拿到需要回填的数据就可以进行数据回填操作

//根据接口返回信息对文档进行回填
const getInformationBackfilling = () => {
  detailObj(props.fileObj?.projectid || props.projectid ).then(res => {
    const { data } = res
     //解析JSON格式的回填数据
    const recruitcontent = JSON.parse(data.recruitcontent)
    //保存预设的书签内容的回填信息,字段需要对应在文档中打的标记书签
      allData.value = {
        projectname: data.projectname,
        projectcode: data.projectcode,
        recrunit: data.recrunit,
        abbreviation: data.projectname,
      }
    // 执行书签回显业务
      setBookmarks()
   // 获取表格回显内容
      const list = recruitcontent.map((item, index) => {
        item.indexNumber = index + 1
        item.projectName = data.projectname
        item.subProjectDl = ""
        return item
      })
   // 执行表格回显业务
      addTable(list, 1)
 })
}

6. 书签回显业务

//书签赋值
const setBookmarks = async () => {
  const app = instance.Application;
  // 书签对象
  const bookmarks = await app.ActiveDocument.Bookmarks;
  let replaceArr = [];
  needSet.forEach((item) => {
    let { key } = getKey(item.name);
    replaceArr.push({
      name: item.name,
      type: 'text',
      value: allDataInfo.value[key]?.toString(),
    });
  });
  // 替换书签内容
  const isReplaceSuccess = await bookmarks.ReplaceBookmark(replaceArr);
}

7. 表格回显业务

//插入表格(标的物)
const addTable = async (list, type) => {
  if (!list && list?.length == 0) return;
  const app = instance.Application;
  let tabelHeade = [
    {
      title: '序号',
      key: 'indexNumber',
    },
    {
      title: '项目名称',
      key: 'projectName',
    },
    {
      title: '子目名称',
      key: 'subProjectName',
    },
    {
      title: '技术服务内容',
      key: 'techServiceContent',
    },
    {
      title: '单位',
      key: 'unit',
    },
    {
      title: '数量',
      key: 'quantity',
    },
    {
      title: '备注',
      key: 'remark',
    },
  ];

  const tables = await app.ActiveDocument.Tables;
  // 等待表格创建完成
  await new Promise(resolve => {
    const interval = setInterval(async () => {
      const currentCount = await tables.Count;
      if (currentCount >= 10) {
        clearInterval(interval);
        resolve();
      }
    }, 300);
  });
  setTimeout(async () => {
    // 获取页面中总表格数量
    const count = await tables.Count;
    const Bookmark = await app.ActiveDocument.Bookmarks.Item('定义的表格书签名');
    // 插入表格
    await tables.Add(
        Bookmark.Range, // 位置信息
        list.length + 1, // 新增表格的行数
        tabelHeade.length, // 新增表格的列数
        1,
        2,
    );
    const tableOne = await tables.Item(Bookmark);
    for (let i = 0; i < list.length + 1; i++) {
      for (let j = 0; j < tabelHeade.length; j++) {
        const curCell = await tableOne.Rows.Item(i + 1).Cells.Item(j + 1);
        const rowText = await curCell.Range;
        // 设置单元格内容的字号
        const font = await rowText.Font;
        font.Size = 12; // 设置字号为 12
        rowText.Text = i == 0 ? tabelHeade[j].title : list[i - 1][tabelHeade[j].key] ? list[i - 1][tabelHeade[j].key].toString() : "";

      }
    }
  }, 1000 * 1.5);

};

8. 扩展内容合并单元格

// 合并行表格单元格 instance:WebOfficeSDK初始化的文档容器,tableIndex:表格编号, rowIndex:开始行,startColIndex:结束行  , value: 替换值)
async function mergeTableCells(instance, tableIndex, rowIndex, startColIndex, endColIndex, value) {
  const app = instance.Application;
  const doc = app.ActiveDocument;
  const tables = await doc.Tables;

  // 获取指定表格
  const table = await tables.Item(tableIndex);

  // 获取指定行
  const row = await table.Rows.Item(rowIndex);

  // 获取起始单元格和结束单元格
  const startCell = await row.Cells.Item(startColIndex);
  const endCell = await row.Cells.Item(endColIndex);

  // 合并单元格
  await startCell.Merge(endCell);
  // 设置合并后单元格的值
  const mergedCell = await row.Cells.Item(startColIndex);
  const mergedCellRange = await mergedCell.Range;
  mergedCellRange.Text = value;
}

// 合并列表格单元格(instance:WebOfficeSDK初始化的文档容器,tableIndex:表格编号, startRowIndex:开始列,endRowIndex:结束列, value: 替换值 )
async function mergeFirstColumnRows(instance, tableIndex, startRowIndex, endRowIndex, value) {
  const app = instance.Application;
  const doc = app.ActiveDocument;
  const tables = await doc.Tables;

  // 获取指定表格
  const table = await tables.Item(tableIndex);

  // 获取起始行和结束行
  const startRow = await table.Rows.Item(startRowIndex);
  const endRow = await table.Rows.Item(endRowIndex);

  // 获取第一列的起始单元格和结束单元格
  const startCell = await startRow.Cells.Item(1);
  const endCell = await endRow.Cells.Item(1);

  // 合并单元格
  await startCell.Merge(endCell);
  // 设置合并后单元格的值
  const mergedCell = await table.Rows.Item(startRowIndex).Cells.Item(1);
  const mergedCellRange = await mergedCell.Range;
  mergedCellRange.Text = value;
}

小结:

1. 根据业务需求,首先初始化时,实现了文档在线查看的功能,根据是否需要编辑的状态设置文档只读模式或者编辑模式;

2. 实现回填功能中,根据拿到的需要回填的数据做处理对应给需要回填的书签内容区域

3. 回填表格功能,根据表头配置好对应回显字段,进行业务回填,增加扩展功能对表格中部分地方单元格合并的方法;

功能代码是已实现的业务逻辑,中间也踩坑不少,最终实现文档在线查看,在线编辑以及文本和表格回填功能,欢迎大家多多交流沟通,提出建议,指出错误,我们一起成长,最后希望大家在踩坑路上继续成长。

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

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

相关文章

PySide6 GUI 学习笔记——常用类及控件使用方法(多行文本控件QTextEdit)

文章目录 PySide6.QtWidgets.QTextEdit 应用举例概述核心特性常用方法文本内容操作光标和选择操作格式和样式查找功能视图控制状态设置常用信号 代码示例示例说明1. 基本设置2. 文本格式化功能3. 功能按钮4. 信号处理 PySide6.QtWidgets.QTextEdit 应用举例 概述 QTextEdit 是…

【版本控制】Git 和 GitHub 入门教程

目录 0 引言1 Git与GitHub的诞生1.1 Git&#xff1a;Linus的“两周奇迹”&#xff0c;拯救Linux内核1.2 GitHub&#xff1a;为Git插上协作的翅膀1.3 协同进化&#xff1a;从工具到生态的质变1.4 关键历程时间轴&#xff08;2005–2008&#xff09; 2 Git与GitHub入门指南2.1 Gi…

基于python大数据的水文数据分析可视化系统

博主介绍&#xff1a;高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实实在…

人工智能学习09-变量作用域

人工智能学习概述—快手视频 人工智能学习09-变量作用域—快手视频

DJango知识-模型类

一.项目创建 在想要将项目创键的目录下,输入cmd (进入命令提示符)在cmd中输入:Django-admin startproject 项目名称 (创建项目)cd 项目名称 (进入项目)Django-admin startapp 程序名称 (创建程序)python manage.py runserver 8080 (运行程序)将弹出的网址复制到浏览器中…

【Redis】笔记|第10节|京东HotKey实现多级缓存架构

缓存架构 京东HotKey架构 代码结构 代码详情 功能点&#xff1a;&#xff08;如代码有错误&#xff0c;欢迎讨论纠正&#xff09; 多级缓存&#xff0c;先查HotKey缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新…

基于规则的自然语言处理

基于规则的自然语言处理 规则方法形态还原&#xff08;针对英语、德语、法语等&#xff09;中文分词切分歧义分词方法歧义字段消歧方法分词带来的问题 词性标注命名实体分类机器翻译规则方法的问题 规则方法 以规则形式表示语言知识&#xff0c;强调人对语言知识的理性整理&am…

使用MounRiver Studio Ⅱ软件写一个CH592F芯片的ADC采集程序,碰到的问题

MounRiver Studio Ⅱ 默认是不开启浮点计算的&#xff0c;所以有些浮点功能不能用&#xff0c;碰到问题是 while (1) {DelayMs (100);tmp Read_Temperature (0);sprintf (tempBuffer, "temp:%.2f\r\n", tmp); // 格式化温度值到字符串。使用%f要开启相应的…

简约商务年终工作总结报告PPT模版分享

简约精致扁平化商务通用动画PPT模版&#xff0c;简约大气素雅商务PPT模版&#xff0c;商务PPT模版&#xff0c;商业计划书PPT模版&#xff0c;IOS风商务通用PPT模版&#xff0c;公司介绍企业宣传PPT模版&#xff0c;创业融资PPT模版&#xff0c;创意低多边形PPT模版&#xff0c…

深度学习学习率优化方法——pytorch中各类warm up策略

warm-up具体原理以及为什么这么做在之前的博客有介绍&#xff0c;这里直接介绍如何直接使用pytorch中的warm-up策略&#xff0c;在pytorch中对于warm-up所有支持的方法都有描述&#xff0c;可以直接阅读1。 深度学习中各类学习率优化方法(AdaGrad/RMSprop/Adam/Warm-UP)原理及其…

分类数据集 - 场景分类数据集下载

数据集介绍&#xff1a;自然场景分类数据集&#xff0c;真实场景高质量图片数据&#xff1b;适用实际项目应用&#xff1a;自然场景下场景分类项目&#xff0c;以及作为通用场景分类数据集场景数据的补充&#xff1b;数据集类别&#xff1a;buildings、forest、glacier、mounta…

leetcode.多数元素

169. 多数元素 - 力扣&#xff08;LeetCode&#xff09; import java.util.HashMap;public class LeetCode169 {public int majorityElement(int[] nums) {int count nums.length;int res count/2;Scanner scanner new Scanner(System.in);HashMap<Integer,Integer> …

Server - 使用 Docker 配置 PyTorch 研发环境

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/148421901 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 建议使…

2025年渗透测试面试题总结-腾讯[实习]安全研究员(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]安全研究员 1. 自我介绍 2. SQL二次注入原理 3. 二次注入修复方案 4. SQL注入绕WAF&#xff…

01-VMware16虚拟机详细安装

官网地址&#xff1a;https://www.vmware.com/cn.html 1.1 打开下载好的 .exe 文件&#xff0c; 双击安装。 1.2 点击下一步 1.3 先勾选我接受许可协议中的条款&#xff0c;然后点击下一步 1.4 自定义安装路径&#xff0c;注意这里的文件路径尽量不要包含中文&#xff0c;完成…

sql列中数据通过逗号分割的集合,按需求剔除部分值

前置 不会REGEXP 方法的需要在这里学习一下下 记sql字段逗号分隔&#xff0c;通过list查询 功能点 现有一个表格中一列存储的是标签的集合&#xff0c;通过逗号分割 入下&#xff1a; 其中tag_ids是逗号分割的标签&#xff0c;现在需要删除标签组中的一些标签&#xff0c;因…

下一代设备健康管理解决方案:基于多源异构数据融合的智能运维架构

导语&#xff1a; 在工业4.0深度演进的关键节点&#xff0c;传统设备管理面临数据孤岛、误诊率高、运维滞后三大致命瓶颈。本文解析基于边缘智能与数字孪生的新一代解决方案架构&#xff0c;并实测验证中讯烛龙PHM-X系统如何通过多模态感知→智能诊断→自主决策闭环&#xff0c…

深入理解JavaScript设计模式之闭包与高阶函数

目录 前言小序一场失败面试面试后的觉醒 闭包变量作用域&#xff1a;谁的地盘听谁的变量的生命周期&#xff1a;该走了&#xff0c;不该走的还在闭包的更多作用&#xff1a;不只是谈恋爱&#xff0c;还能干活&#xff01;1、封装私有变量&#xff1a;你的变量我来守护2、延长变…

springboot启动mapper找不到方法对应的xml

数据源配置 目录结构 idea中mapper.java 可以找到对应的mapper.xml文件 启动却找不到 因为mapper.db1会被识别为文件名 而非目录结构 调整为这种

MQTT协议:物联网时代的通信基石

MQTT协议&#xff1a;物联网时代的通信基石 在当今快速发展的物联网&#xff08;IoT&#xff09;时代&#xff0c;设备之间的通信变得尤为重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;协议作为一种轻量级的消息传输协议&#xff0c;正逐渐成为物联…