• vue项目前端导出word文件(bug解决)


    摘要:之前项目中导出价格表是由后端实现,前端只需要调用接口下载word即可,后来业务改变比较大,word模版需要一直改动,后端改起来相对麻烦,后来直接前端自己定义模版,实现下载word文档。

    一、需要安装的依赖

    1、docxtemplater

    介绍:docxtemplater是一种邮件合并工具,它以编程方式使用,处理条件、循环,并且可以扩展为表格、HTML、图像等。

    安装方法:cnpm i docxtemplater@^3.9.1

    2、FileSaver

    介绍:FileSaver.js 是在客户端保存文件的解决方案,非常适合需要生成文件,或者保存不应该发送到外部服务器的敏感信息的应用。

    安装方法:cnpm i file-saver@^1.3.8

    3、jszip

    介绍:jszip是一个用于创建、读取和编辑.zip文件的JavaScript库,且API的使用也很简单。

    安装方法:cnpm i jszip@^2.6.1

    4、jszip-utils

    介绍:jszip-utils是与jszip一起使用的跨浏览器的工具库

    安装方法:cnpm i jszip-utils@^0.0.2

    二、创建word模版

    介绍:根据自己的业务需求创建需要导出的word模版,变量数据使用{变量名}代替,表格内容数据需要使用{#参数名}开始{/参数名}结尾,具体如下图:

    注意点:1.模板文件使用vue-cli2的时候,放在static目录下。使用vue-cli3的时候,放在public目录下。

                2.文件须以docx结尾。

    不然可能出现的问题:提示Uncaught Error: Corrupted zip: missing 7124 bytes.

    vue-cli3示例位置如图:

    三、html代码编写

    定义下载事件downloadprice

    <div class="download” @click="downloadprice">下载价格表</div>

    四、script代码编写

    1.使用的页面中导入需要的插件:

    import Docxtemplater from 'docxtemplater';
    import { saveAs } from 'file-saver';
    import JSZip from 'jszip';
    import JSZipUtils from 'jszip-utils';

    2.定义接口数据(这里为定义好的数据,正常情况下通过接口获取需要在word文档上展示的数据):

    data() {
      return {
          // 导出价格表全部信息
        exportPriceObj: {
          actualPayFee: '179.55',
          deliveryFee: '0.00',
          discountActualFee: '179.55',
          discountFee: '9.45',
          discountRatio: '95',
          nickName: '张三',
          retailTotalFee: '0.00',
          totalFee: '189.00',
        },
        // 导出价格表商品信息
        exportPriceListOne: [
          {
            productColor: '白色',
            productName: '0909测试商品',
            productNo: 1,
            productSize: '4XL(58)',
            productSkuId: 'teydnkn',
            sellingPrice: '10.00',
          },
          {
            productColor: '白色',
            productName: '1955测试商品',
            productNo: 2,
            productSize: 'XL(52)',
            productSkuId: 'teydoja',
            sellingPrice: '40.00',
          }
        ],
      }
    }

    3.下载word文档点击事件方法:

    // 下载价格表
    downloadprice() {
      let _this = this;
      // 判断有无附加商品来选择word模版
      // 读取并获得模板文件的二进制内容
      JSZipUtils.getBinaryContent('pricenew.docx', function(error, content) {
        console.log('-----', content);
        // input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
        // 抛出异常
        if (error) {
          throw error;
        }
        // 创建一个JSZip实例,内容为模板的内容
        let zip = new JSZip(content);
        console.log('+++++', zip);
        // 创建并加载docxtemplater实例对象
        let doc = new Docxtemplater();
        console.log('/////', doc);
        doc.loadZip(zip);
        console.log('=====', doc);
        // 设置模板变量的值
        doc.setData({
          // 导出价格表全部信息
          ..._this.exportPriceObj,
          // 导出价格表商品信息
          tableone: _this.exportPriceListOne,
        });
        try {
          // 用模板变量的值替换所有模板变量
          doc.render();
        } catch (error) {
          // 抛出异常
          let e = {
            message: error.message,
            name: error.name,
            stack: error.stack,
            properties: error.properties
          };
          console.log(JSON.stringify({ error: e }));
          throw error;
        }
        // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
        let out = doc.getZip().generate({
          type: 'blob',
          mimeType:
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        });
        // 将目标文件对象保存为目标类型的文件,并命名
        saveAs(out, _this.exportPriceObj.nickName + '的价格表.docx');
      });
    },

    4.点击下载后可能会出现的问题:

    一、提示Uncaught Error: Corrupted zip: missing 7124 bytes.

    错误方法如图:

    可能产生的原因是:1.模版文件word放置的位置获取不到;

                               2.word文档格式出现错误;

    解决方法:1.模板文件使用vue-cli2的时候,放在static目录下。使用vue-cli3的时候,放在public目录下。

                   2.文件须以docx结尾。

    正确方法如图:

    二、提示Uncaught Error: Can't find end of central directory : is this a zip file ?

    错误方法如图:

    可能产生的原因是:1.你项目里面引用了mockjs文件,它的原理是重写了XMLHttpRequest,导致你上报插件找不到对应的方法;

    解决方法:上线时把项目中引入的mock注释掉,// import '@/mock';

    原理分析:mockjs是一个模拟后台接口的JS库,它的原理是重写了XMLHttpRequest,它可以在接口没出来时非常方便的模拟数据,上线之后      不引用它即可。一般上报插件中会使用原生XMLHttpRequest,而原生XMLHttpRequest已被mockjs覆盖找不到相应的方法,所以会   出错。除了mockjs之外,zonejsoboejsfetchjs也有自己的的XMLHttpRequest库,请慎用。

    正确方法如图:

    五、导出结果

    导出结果如图:

    有问题欢迎留言,带上问题和代码截图,看到后第一时间回复帮忙解答,谢谢!

  • 相关阅读:
    2013-2014-2(复变函数56)
    2015-2016-1(实变函数56)
    2014-2015-2(常微分方程64, 数学分析提高64)
    2015-2016-2(点集拓扑56, 点集拓扑56)
    2016-2017-2(点集拓扑56, 点集拓扑56)
    2016-2017-1(实变函数56, 点集拓扑56)
    2017-2018-1(实变函数56, 点集拓扑56)
    2013-2014 指导2014届毕业生8名(48)
    2015-2016 指导2016届毕业生8名(48)
    2014-2015 指导2015届毕业生8名(48)
  • 原文地址:https://www.cnblogs.com/hejun26/p/13647927.html
Copyright © 2020-2023  润新知