docxtemplater+vue+docxtemplater-image-module-free export word document (including pictures)
Install required plugins
npm install jszip-utils
npm install docxtemplater
npm install jszip
npm install file-saver
npm install docxtemplater-image-module-free
create a word template
放项目的publid文件夹
The normal data is {title}
image{%imgUrl}
cycle {#list}{/list}
as follows
Process pictures as Base46
Notice:如果出现跨域的问题,需要后端帮忙生成Base46(PS:别傻乎乎自己搞,搞半天都搞不定)
The front end obtains Base46:
/**
* 将图片的url路径转为base64路径
* @param {Object} imgUrl 图片路径
*/
getBase64Sync(imgUrl) {
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open("get", imgUrl, true);
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == 200) {
//得到一个blob对象
var blob = this.response;
console.log("blob", blob)
// 至关重要
let oFileReader = new FileReader();
oFileReader.onloadend = function (e) {
// 此处拿到的已经是base64的图片了,可以赋值做相应的处理
console.log(e.target.result)
}
oFileReader.readAsDataURL(blob);
}
}
xhr.send();
}
The back-end acquisition plus this.base64 = 'data:image/png;base64,' + res.data
the code on the official website after acquisition is as follows
base64DataURLToArrayBuffer(dataURL) {
const base64Regex = /^data:image\/(png|jpg|jpeg|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;
},
export word
// word导出
let _this = this;
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent("test.docx", function (error, content) {
// 1.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
// 抛出异常
if (error) {
throw error;
}
// 图片处理
let opts = {
};
opts.centered = false; // 图片居中,在word模板中定义方式为{%%image}
opts.fileType = "docx";
opts.getImage = function (chartId) {
return _this.base64DataURLToArrayBuffer(chartId);
};
opts.getSize = function () {
return [150, 35];
};
let imageModule = new ImageModule(opts);
// 创建一个JSZip实例,内容为模板的内容
const zip = new JSZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater();
doc.attachModule(imageModule);
doc.loadZip(zip);
=
// 设置模板变量的值
doc.setData({
..._this.list,
list: _this.data,//需要循环的数据
imgUrl : _this.base64,//图片获取的base6
});
try {
// 用模板变量的值替换所有模板变量
doc.render();
} catch (error) {
// 抛出异常
const e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties,
};
console.log(
e
);
throw error;
}
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
// 将目标文件对象保存为目标类型的文件,并命名
saveAs(out, "成绩单.docx");
});
Note that if the data returned by the backend is null, the export will appear as undefined, remember to convert it to an empty string