vue+wangEditor输出word文档(包含图片,表格)--亲测有效

5,900 阅读1分钟

项目需求,做一个可以输出word的富文本,选了wangEditor。并且结合fileSave和jquery相关包,达成需求。

第一步:引入wangEditor,并封装成组件

首先,从网上找了一个封装好的editor组件,手动添加了一个loading动画(iview用起来好难受)。

关于图片上传的方法也没有用到,因为这个编辑器支持base64,直接在代码里开启就可以。

参考文档:segmentfault.com/a/119000001…

<template>
  <div>
    <div v-if="isLoad" class="demo-spin-container" style="z-index: 2000000;">
      <Spin size="large" fix></Spin>
    </div>

    <div id="wangeditor">
      <div ref="editorElem" style="text-align: left"></div>
    </div>
  </div>
</template>
<script>
import E from "wangeditor";
export default {
  name: "editorElem",
  data() {
    return {
      editor: null,
      editorContent: "",
    };
  },
  props: ["catchData", "content", "isLoad"], // 接收父组件的方法
  watch: {
    content() {
      this.editor.txt.html(this.content);
    },
  },
  mounted() {
    this.editor = new E(this.$refs.editorElem);
    // console.log('当前编辑器', this.editor);

    this.editor.config.onchange = (html) => {
      this.editorContent = html;
      this.catchData(this.editorContent); // 把这个html通过catchData的方法传入父组件
    };

    this.editor.config.uploadImgShowBase64 = true; // 开启base64

    // this.editor.config.uploadImgServer = "你的上传图片的接口";
    // this.editor.config.uploadFileName = "你自定义的文件名";
    this.editor.config.menus = [
      // 菜单配置
      "head", // 标题
      "bold", // 粗体
      "fontSize", // 字号
      "fontName", // 字体
      "italic", // 斜体
      "underline", // 下划线
      "strikeThrough", // 删除线
      "foreColor", // 文字颜色
      "backColor", // 背景颜色
      // 'link',  // 插入链接
      "list", // 列表
      "justify", // 对齐方式
      // 'quote',  // 引用
      //'emoticon',  // 表情
      "image", // 插入图片
      "table", // 表格
      // 'code',  // 插入代码
      "undo", // 撤销
      "redo", // 重复
    ];
    // 下面是最重要的的方法
    // 但是,我没有用到 - -
    this.editor.config.uploadImgHooks = {
      before: function (xhr, editor, files) {
        // 图片上传之前触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
        // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
        // return {
        //     prevent: true,
        //     msg: '放弃上传'
        // }
      },
      success: function (xhr, editor, result) {
        // 图片上传并返回结果,图片插入成功之后触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
        this.imgUrl = Object.values(result.data).toString();
      },
      fail: function (xhr, editor, result) {
        // 图片上传并返回结果,但图片插入错误时触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
      },
      error: function (xhr, editor) {
        // 图片上传出错时触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
      },
      timeout: function (xhr, editor) {
        // 图片上传超时时触发
        // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
      },

      // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
      // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
      customInsert: function (insertImg, result, editor) {
        // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
        // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果

        // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
        let url = Object.values(result.data); // result.data就是服务器返回的图片名字和链接
        JSON.stringify(url); // 在这里转成JSON格式
        insertImg(url);
        // result 必须是一个 JSON 格式字符串!!!否则报错
      },
    };

    this.editor.create(); // 创建富文本实例
  },
};
</script>
<style lang="less" scoped>
#wangeditor {
  width: 100%;
}

/deep/ .w-e-text-container {
  height: 500px !important;
}

.demo-spin-container {
  left: 500px;
  top: 200px;
  position: absolute;
}
</style>

然后在项目中引用,传3个参数过去

<wangEditor
      class="editor"
      :catchData="catchData"
      :content="content"
      :isLoad="isLoad"
/>

注意第2个参数,这个方法可以获得动态监听到的html标签。

我在项目中的使用如下:

catchData(index) {
      this.htmlDoc = "<div>" + index + "</div>";
      
      // 判断是否存在 border="0"
      const isBorderFlag = this.htmlDoc.match(`border="0"`);

      // 判断是否有复制进去的table
      const isCopyTable = this.htmlDoc.match(`<table>`);

      if (isBorderFlag) {
        this.htmlDoc = this.htmlDoc.replace(/border="0"/g, `border="1"`);
      }
      if (isCopyTable) {
        this.htmlDoc = this.htmlDoc.replace(
          /<table>/g,
          `<table border="1" width="100%" cellpadding="0" cellspacing="0">`
        );
      }
      // console.log(this.htmlDoc);
    },

我使用的时候,在外层包了一层div,并且遇到如下2个坑:

1、在富文本中创建的表格,输出到word文档里没有边框(根据网上的方法,修改了wangEditor.min.js文件还是没用),于是手动判断是否存在表格,再替换掉。

2、从word复制进去的表格,再次输出word时也没有边框,解决办法方法同1。

第二步:引入输出word文档相关文件

参考文档:blog.csdn.net/dwb12345612…

首先引入 2个文件 和 jquery

企业微信截图_16327931543228.png

上面2个文件源码,在参考文档里

import "../../../../libs/FileSaver";
import "../../../../libs/jquery.wordexport";

jquery建议在index.html中使用script引入(我一开始使用cnpm安装,然后main.js引入,一直报错)

第三步:输出word

最后结合wangEditor返回的html标签,输出word

// 导出word文档
    exportWord() {
      $(this.htmlDoc).wordExport("word文档");
    },

参考文档:

segmentfault.com/a/119000001…

blog.csdn.net/dwb12345612…