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

vue

摘要:之前项目中导出价格表是由后端实现,前端只需要调用接口下载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之外,zonejs、oboejs、fetchjs也有自己的的XMLHttpRequest库,请慎用。

正确方法如图:

三、提示 End of data reached (data length = 0, asked index = 4). Corrupted zip ?

错误方法如图:

可能产生的原因:1.你项目上传上去的word文件为空文件;

解决方法:1.请检查你上传到服务器的文件大小是否正确,如果字节为空或者字节大小不对,请替换一个正确的word文件上去;

四、其他问题等

请检查你下载文件方法是否存在缓存,查询方法如下:

304代表有缓存

200代表没有

解决方法:

JSZipUtils.getBinaryContent(\'warehouse.docx?random=\' + Math.random(), function(error, content) {

在引用文件时在文件后面添加一个随机数

五、导出结果

导出结果如图:

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

以上是 vue项目前端导出word文件(bug解决) 的全部内容, 来源链接: utcz.com/z/375871.html

回到顶部