前端实现下载word(docxtemplater)
·
docxtemplater是一个用于处理和生成Word文档的模板引擎
插件准备:npm install --save docxtemplater pizzip jszip-utils jszip file-saver
如果想使用高级语法,可引入以下两个插件, 可解析更多表达式:
npm install --save angular-expressions lodash
1、下载word
tempDocxPath:文件路径(一般放在项目public下)
wordData:数据
fileName:压缩包名字
export const exportWordFormat = (tempDocxPath: string, wordData: object, fileName: string) => {
let promises: any = [];
let jsZip = new JSZip();
let list = Object.values(wordData);
for (let i = 0; i <= list.length - 1; i++) {
let filename = (i+1) + '_' + list[i].realname + ".docx";
const data = list[i];
const promise = new Promise((resovle) => {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(tempDocxPath, async function (error: any, content: any) {
if (error) {
throw error;
}
const imageOpts = {
getImage: function (tagValue, tagName) {
if (tagValue.search(/https:/i) >= 0) {
return new Promise(function (resolve, reject) {
let image = new Image();
image.src = tagValue + "?v=" + Math.random(); // 处理缓存
image.crossOrigin = "*"; // 支持跨域图片
image.onload = function () {
let base64 = drawBase64Image(image);
const base64Value = base64Parser(base64);
resolve(base64Value);
};
image.onerror = function () {
reject(new Error("Image failed to load"));
};
});
}
},
getSize() {
return [100, 100];
},
getProps: function (img, tagValue, tagName) {
return {
align: "left",
};
},
};
const base64Regex = /^data:image\/(png|jpg|png|svg|svg\+xml);base64,/;
function base64Parser(dataURL) {
if (typeof dataURL !== "string" || !base64Regex.test(dataURL)) {
return false;
}
const stringBase64 = dataURL.replace(base64Regex, "");
if (typeof Buffer !== "undefined" && Buffer.from) {
return Buffer.from(stringBase64, "base64");
}
const binaryString = window.atob(stringBase64);
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;
}
const imageModule = new ImageModule(imageOpts);
// 创建一个PizZip实例,内容为模板的内容
const zip = new PizZip(content);
expressions.filters.lower = function (input: any) {
if (!input) return input;
return input.toLowerCase();
};
function angularParser(tag: any) {
tag = tag.replace(/^\.$/, "this").replace(/(’|‘)/g, "'").replace(/(“|”)/g, '"');
const expr = expressions.compile(tag);
return {
get: function (scope: any, context: any) {
let obj = {};
const index = last(context.scopePathItem);
const scopeList = context.scopeList;
const num = context.num;
for (let i = 0, len = num + 1; i < len; i++) {
obj = assign(obj, scopeList[i]);
}
obj = assign(obj, { $index: index });
return expr(scope, obj);
},
};
}
// 创建并加载docxtemplater实例对象
const doc = new Docxtemplater()
.loadZip(zip)
.setOptions({
paragraphLoop: true,
linebreaks: true,
parser: angularParser,
})
.attachModule(imageModule)
.compile();
let params = {}
params = {
realname: data.realname || " ", // 姓名
sex: data.sex || " ", // 性别
option: data.option_config
}
doc.renderAsync(params).then(function () {
const out = doc.getZip().generate({
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
if (list.length > 1) {
jsZip.file(filename, out, { binary: true });
if (i == list.length - 1) {
jsZip.generateAsync({ type: "blob" }).then((content) => {
saveAs(content, fileName);
});
}
} else {
saveAs(out, `${data.realname}.docx`);
}
});
});
resovle(true);
});
promises.push(promise);
}
};
2、下载调查表,对勾
首先写好word模板,处理好数据格式
模板中写法:输入大写R,选中之后修改字体为wingding2即可转成对勾框
{#option}{name}{#op} {name}{checked}{/op}{/}
选中{checked}修改字体为wingding2
代码处理:
data[i].option_config = data[i].option_config.map((item:any) => ({
name: item.name,
op: [
{ name: "很好", checked: item.option == 1 ? "☑" : "□" },
{ name: "一般", checked: item.option == 2 ? "☑" : "□" },
{ name: "不满意", checked: item.option == 3 ? "☑" : "□" }
]
}));
数据格式如下:
option_config:[
{
name: "学习过程中",
op:[{name: '很好', checked: '□'},
{name: '一般', checked: '□'},
{name: '不满意', checked: '□'}
]
},
]
3、docxtemplater语法
a:'变量渲染'
1、变量渲染:{a}
img:'https:dhfjkfhk'
2、图片渲染:{%img}
let list = [{name: '张三', age: 12}, {name: '李四', age: 23}];
3、循环:{#list}{name}{age}{/} 或者 {#list}{name}{age}{/list}
let list2 = [{name: '张三', sex: 0}, {name: '李四', sex: 1];
4、循环+判断
{#list2}{#sex == 0}男{/sex == 0}{#sex == 1}女{/sex == 1}{/}
更多推荐




所有评论(0)