- 作者:老汪软件技巧
- 发表时间:2024-09-24 07:02
- 浏览量:
需求
在开发过程中遇到一个需求,动态生成一个word报表,当时考虑了是前端做还是后端做的问题,最后发现两个解决需求的方法都大差不差,但考虑到前端少发一个请求,就此使用的前端来解决。
首先,我们需要安装以下几个库:
npm i docxtemplater 是一个用于基于模板生成动态 `.docx` 文档的 JavaScript 库。它允许你将动态数据填充到 `.docx` 模板文件中
npm i jszip-utils 用于在浏览器中处理 ZIP 文件的工具库
npm file-saver 是一个用于在浏览器中保存文件的 JavaScript 库
创建一个工具函数,用于加载 .docx 模板,填充数据并生成文档。
//引入工具
import PizZip from 'pizzip';
import Docxtemplater from 'docxtemplater';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';
// 加载 .docx 模板文件
function loadFile(url, callback) {
JSZipUtils.getBinaryContent(url, callback);
}
// 下载生成的文档
export function download(file, name) {
saveAs(file, name);
}
// 生成并下载 Word 文档(templatePath是word文档模版地址,data是对应的数据)
export function generateWordDocument(templatePath, data) {
return new Promise((resolve, reject) => {
loadFile(templatePath, function (error, content) {
if (error) {
reject(new Error(`Error loading template file: ${error.message}`));
return;
}
try {
// 加载模板文件内容到 PizZip
const zip = new PizZip(content);
const doc = new Docxtemplater(zip, {
paragraphLoop: true,
linebreaks: true,
});
// 设置模板中的占位符数据
doc.setData(data);
// 渲染文档
doc.render();
// 生成最终的文档 Blob
const fileWord = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
});
// 返回生成的文档 Blob
resolve(fileWord);
} catch (error) {
console.error('Error rendering document:', error);
reject(new Error(`Error rendering document: ${error.message}`));
}
});
});
}
在需要的组件内调用
<div>
<button @click="startGeneration">生成文档button> <button @click="downloadWord" :disabled="!generatedFile">下载文档button>
div>
<script setup>
import { ref } from 'vue';
import { generateWordDocument, download } from '../utils/wordGenerate.js';
const generatedFile = ref(null);
// 模板文件的路径,一般放在 public 目录中
const templatePath = '/template.docx';
const data = { name: '测试', date: '2024-09-23' };
const startGeneration = async () => {
try {
generatedFile.value = await generateWordDocument(templatePath, data);
console.log('文档生成成功');
} catch (error){
console.error('Error generating document:', error);
}
};
//文档下载
const downloadWord = () => {
if (generatedFile.value) {
download(generatedFile.value, 'generated-document.docx');
} else {
console.error('No file generated');
}};
script>
就此功能完成了,当然如果需求是生成成功的同时就下载文档,可以将下载功能直接写在生成功能内,就可以省去异步处理的代码量。