首页 前端知识 vue使用docx-preview实现在线预览编辑word文档根据选择联动改变word

vue使用docx-preview实现在线预览编辑word文档根据选择联动改变word

2024-03-27 10:03:49 前端知识 前端哥 911 261 我要收藏

实现功能:

  1. 在线预览word文档(oss在线地址转blob对象预览)
  2. 根据选项或输入内容在线更改word对应的字段(包含多个匹配)
  3. 每次更改跳转到第一个匹配的地方(居中显示并且高亮显示)

实现效果:

实现思路:

word文档中需要根据用户控制的需要每一个配置一个独有代码如合同编号为${HTBH},初始化的时候我们可以先把word加载出来,等dom加载完毕我们在每一个含有${}符号的dom上增加一个独有类,这样我们就可以通过js的dom查询查找用户改变的dom,并在dom上进行处理替换文本显示值,跳转到可视区域中心显示,记录每次key增加样式高亮显示并移除上一次的高亮样式。

具体实现过程:

使用了docx-preview插件,也可以去看看预览demo

我这里是vue实现的,首先引入插件

npm i docx-preview --save

实现代码: 

<div class="docWrap">
    <div ref="wordFile"></div>
</div>
activedKey: null, //当前高亮选项key

//初始化word文档
initDocx() {
    const that = this
    const xhr = new XMLHttpRequest();
    //oss文件地址转blob 如果是后端返回文件流可以不转
    let url = this.contract.template_link
    xhr.open("get", url);
    xhr.responseType = "blob";
    xhr.onload = function() {
        const blob = new window.Blob([xhr.response], { type: 'application/docx' }); //转换后blob文件
        docx.renderAsync(blob, that.$refs.wordFile).then((x) => {
            const elements = that.$refs.wordFile.getElementsByTagName('span')
            for (let index = 0; index < elements.length; index++) {
                const item = elements[index];
                //匹配带有${}的元素
                var reg = /\$\{(.+?)\}/;
                var reg_g = /\$\{(.+?)\}/g;
                let result = item.innerHTML.match(reg_g);
                if(result && result.length>0){
                    for (var i = 0; i < result.length; i++) {
                      let items = result[i]
                      //添加独有的类 如visualize-HTBH
                      item.classList.add('visualize-' + items.match(reg)[1])
                    }
                }
            }
        })
    };
    xhr.send();
},
/**
* 选项变化回调
* @param {String} val 改变后的值
* @param {String} key 每项对应的key如HTBH
* @param {String} type 选项类型 如下拉 输入框 日期等
*/
optionChange(val, key, type) {
    const that = this
    let value = val
    if(type == 'select') {
        value = val && val.length > 0 ? val.join(',') : ''
    }
    //找到对应的dom
    let dom = that.$refs.wordFile.getElementsByClassName("visualize-" + key);
    let arrayDom = Array.from(dom)
    if(arrayDom && arrayDom.length > 0) {
        if(this.activedKey) { //上一个高亮显示选项key的类值
          //查找上一个高亮dom
          let aDom = that.$refs.wordFile.getElementsByClassName(this.activedKey);
          let arrayADom = Array.from(aDom)
          if(arrayADom && arrayADom.length > 0) {
            arrayADom.forEach(item => {
              //移除所有上一个高亮显示的样式
              item.classList.remove("actived-color");
            });
          }
        }
        //存储当前高亮显示选项key的类值以便下次查找
        this.activedKey = "visualize-" + key
        //屏幕滚动到第一个匹配的dom
        arrayDom[0].scrollIntoView();
        arrayDom.forEach(item => {
          //替换内容
          item.innerHTML = value
        });
    }
},
.actived-color {
    background-color: rgba(10, 224, 8, .1);
}
转载请注明出处或者链接地址:https://www.qianduange.cn//article/4195.html
评论
会员中心 联系我 留言建议 回顶部
复制成功!