前端doc插件,docx-preview +docxtemplater + vue3 在线word报告回填

938 阅读1分钟

docx-preview +docxtemplater + vue3 在线word报告回填实战

根据用户需求,需要提供一份根据系统数据生成的在线word报告,并包含可导出下载后重新上传等功能。
通过调研了解到可以使用docxtemplater替换掉word文档中的模板内,详情参考blog.csdn.net/Coludidi/ar…内容。
docxtemplater是个十分强大的工具,有兴趣可以多多了解docxtemplater.com/
计划使用docxtemplater将系统生成数据替换掉模板内容后再使用docx-preview展示。
一、依赖导入
// 安装 docxtemplater
npm install docxtemplater pizzip --save

// 安装 jszip-utils
npm install jszip-utils --save

// 安装 jszip
npm install jszip --save

// 安装 docx-preview
npm install docx-preview --save

二、代码示例
1.docxtemplater替换模板内容:
① 需要准备一个word模板文件(按自己所需最后导出的样式),例如:

image.png

② 将word模板文档内容导入,通过JSZipUtils处理将docx类型的文件内容转换成压缩文件数据流,然后通过PizZip将压缩文件数据流转换成docxtemplater可加载的数据。

const getWordContent = () => {
  JSZipUtils.getBinaryContent(baseUrl + "/assets/tempalte.docx"
			(error, content) => {
				if (error) {
					throw error;
				}
				initWordContent(content);
			}
		);
}
const initWordContent = content => {
	console.log(content);
	let zip = new PizZip(content);
	let doc = new docxtemplater();
	let docTempateData = {
		applyDeptName: "test11",
		applyDate: "test11",
		taskDeptName: "test11",
		LocationName: "", //...
  }
	doc.loadZip(zip);
	//获取数据
	doc.setData(docTempateData); //模板数据替换模板字符
	try {
		doc.render();
	} catch (error) {
		let e = {
			message: error.message,
			name: error.name,
			stack: error.stack,
			properties: error.properties
		};
		throw error;
	}
  // 将docxtemplater内容转换压缩,供docx-preview加载
	let out = doc.getZip().generate({
		type: "blob",
		mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
	});

③ 使用docx-preview提供的renderAsync方法在页面中渲染文档数据。

// out: docxtemplater处理过后的数据, exportDomRef.value: 文档预览挂载dom
renderAsync(out, exportDomRef.value).then(x => {
		const elements = exportDomRef.value.getElementsByTagName("span");

		for (let index = 0; index < elements.length; index++) {
			const item = elements[index];
			if (item.innerHTML == "5") {
				item.style.dispaly == "none";
				item.classList.add("spanHidden");
			}
			//匹配带有${}的元素
			let reg = /\$\{(.+?)\}/;
			let reg_g = /\$\{(.+?)\}/g;
			let result = item.innerHTML.match(reg_g);
			if (result && result.length > 0) {
				for (let i = 0; i < result.length; i++) {
					let items = result[i];
					//添加独有的类 如visualize-HTBH
					item.classList.add("visualize-" + items.match(reg)[1]);
				}
			}
		}
		loading.value = false;
	});