通过word模板输出完整word文件,纯前端vue
参考文档:
https://docxtemplater.com/docs/api/
https://www.freesion.com/article/42641217365/
https://sg.jianshu.io/p/0de31429b12a
https://www.cnblogs.com/xz233/p/14450831.html
模板文件:
package.json
-- 安装 docxtemplater
cnpm install docxtemplater pizzip --save
-- 安装 jszip-utils
cnpm install jszip-utils --save
-- 安装 jszip
cnpm install jszip --save
-- 安装 FileSaver
cnpm install file-saver --save
没有cnpm可以使用npm
"file-saver"
: "^2.0.5",
"jszip": "^3.6.0",
"jszip-utils": "^0.1.0",
"open-docxtemplater-image-module": "^1.0.3",
"pizzip": "^3.0.6",
"angular-expressions": "^1.1.3",
"docxtemplater": "^3.21.2",
"docxtemplater-image-module-free": "^1.1.1"
引入
import docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import {
saveAs
} from 'file-saver'
1、获取echarts图表
// ECHARTS图表的图片并转为base64格式
let thisImage = hideEcharts.getDataURL({
pixelRatio: 2, // 导出的图片分辨率比例,默认为 1。
backgroundColor: '#fff' // 导出的图片背景色,默认使用 option 里的 backgroundColor
});
2、模板blob文件流获取
/**
* 上传word至服务器
* */
exportWord: function (item, thisImage, isDownLoad) {
// 这里要引入处理图片的插件,下载docxtemplater后,引入的就在其中了
var ImageModule = require('docxtemplater-image-module-free');
var fs = require("fs");
const expressions = require("angular-expressions");
let _this = this;
// 读取并获得模板文件的二进制内容,放在项目中即可
JSZipUtils.getBinaryContent('/apis/access/pfm/pfmTemplate/一次调频报告模板.docx', function (error, content) {
if (error) {
console.log(error)
throw error;
}
// 图片处理
let opts = {}
opts = {centered: false};
opts.getImage = (chartId) => {
return _this.base64DataURLToArrayBuffer(chartId);
}
opts.getSize = function (img, tagValue, tagName) {
//自定义指定图像大小,此处可动态调试各别图片的大小
if (tagName === "image") return [550, 280];
return [550, 280];
}
// 创建一个PizZip实例,内容为模板的内容
let zip = new PizZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater();
doc.attachModule(new ImageModule(opts));
doc.loadZip(zip);
// 写入word参数调整
if (item.qualified == 'T') {
item.qualified = '合格'
} else {
item.qualified = '不合格'
}
// 设置模板变量的值
doc.setData({
...item,
image: thisImage
});
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"
});
// 将目标文件对象保存为目标类型的文件,并命名
_this.uploadFile(out, item, isDownLoad)
// saveAs(out, "一次调频数据记录.docx");
});
},
3、官方图片转换
/**
* 导出echarts图片,格式转换,官方自带,不需要修改
* */
base64DataURLToArrayBuffer(dataURL) {
const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/;
if (!base64Regex.test(dataURL)) {
return false;
}
const stringBase64 = dataURL.replace(base64Regex, "");
let binaryString;
if (typeof window !== "undefined") {
binaryString = window.atob(stringBase64);
} else {
binaryString = new Buffer(stringBase64, "base64").toString("binary");
}
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
const ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes.buffer;
},
4、服务器上传
/**
* 报告上传服务器
* */
uploadFile(file, item, isDownLoad) {
let formData = new window.FormData();
formData.append('file', file);
formData.append('id', item.pid);
formData.append('startTimeStr', item.startTimeStr);
let options = {
url: '/apis/pfm/blobFileWrite',
data: formData,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
}
};
return axios(options)
.then(resp => {
// 上传服务器成功
if (resp.data.code == 200) {
// 如果需要下载
if (isDownLoad) {
this.wordDownLoadAxios(item.pid)
}
}
})
},