前言
Docxtemplater是一个用于生成和操作Word文档的JavaScript库,它允许开发者在前端动态生成和编辑Word文档,用于动态生成报表等功能。
使用方法
安装依赖:首先,你需要安装Docxtemplater及其相关依赖。可以通过npm安装这些库:
pnpm install docxtemplater pizzip jszip-utils file-saver docxtemplater-image-module-free
引入依赖:在项目中引入必要的模块:
import Docxtemplater from 'docxtemplater'; import PizZip from 'pizzip'; import { saveAs } from 'file-saver';
创建模板文档:在public文件下创建.docx模板文档,变量用大括号包裹。{#变量}表示循环 {%变量}可以放置图片
模板数据匹配:在页面中创建对象进行字段对应
<template> <div> <!-- 下载和打印按钮 --> <button @click="downloadDocument"> Download Document </button> <button v-if="outputDoc" @click="printDocument">Print Document</button> <!-- 错误提示 --> <div v-if="errorMessage" style="color: red"> {{ errorMessage }} </div> </div> </template> <script setup> import { ref, onMounted } from "vue"; import Docxtemplater from "docxtemplater"; import PizZip from "pizzip"; import { saveAs } from "file-saver"; import axios from "axios"; const ImageModule = require("docxtemplater-image-module-free");//处理图片 const errorMessage = ref(""); // 存储错误信息 const outputDoc = ref(null); // 存储生成的文档 const userData = { name: "John Doe", email: "john.doe@example.com", age: 30, option: [ { id: 1, gender: 1, address: "qqq", }, { id: 2, gender: 2, address: "www", }, { id: 3, gender: 3, address: "eee", }, ], people: [ { position: "CEO", signatureUrl: "http://xxxxxxxxxxx", }, { position: "CTO", signatureUrl: "http://xxxxxxxxxx", }, ], }; // 加载本地模板文件 async function loadTemplate(filePath) { const response = await fetch(filePath); const arrayBuffer = await response.arrayBuffer(); return new Uint8Array(arrayBuffer); } // 下载网络图片并转换为 Base64 async function downloadImageToBase64(url) { const response = await axios.get(url, { responseType: "arraybuffer" }); const base64 = btoa( new Uint8Array(response.data).reduce( (data, byte) => data + String.fromCharCode(byte), "" ) ); return `data:${response.headers["content-type"]};base64,${base64}`; } //图片需要转成ArrayBuffer格式 const 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; }; // 渲染并生成 .docx 文件 async function generateDocx() { // 下载图片并更新数据 for (let employee of userData.people) { employee.signature = await downloadImageToBase64(employee.signatureUrl); } let opts = {}; opts = { // 图像是否居中 centered: false, }; opts.getImage = (chartId) => { // console.log(chartId);//base64数据 // 将base64的数据转为ArrayBuffer return base64DataURLToArrayBuffer(chartId); }; opts.getSize = function (img, tagValue, tagName) { // console.log(img);//ArrayBuffer数据 // console.log(tagValue); //base64数据 // console.log(tagName);//wordData对象的图像属性名 // 自定义指定图像大小或直接返回固定尺寸 return [100, 60]; }; // 加载模板文件 const templateContent = await loadTemplate("/template.docx"); // 假设模板文件在 public 目录 const zip = new PizZip(templateContent); // 初始化 docxtemplater const doc = new Docxtemplater(); doc.attachModule(new ImageModule(opts)); doc.loadZip(zip); doc.setData(userData); try { doc.render(); errorMessage.value = ""; // 清空错误信息 } catch (error) { console.error("渲染错误:", error); errorMessage.value = "Error rendering template. Please check the template and data."; return; } // 生成 .docx 文件 const generatedDoc = doc.getZip().generate({ type: "blob" }); outputDoc.value = generatedDoc; // 触发文件下载 saveAs(generatedDoc, "output.docx"); } // 下载文档 const downloadDocument = () => { // 调用函数 generateDocx(); }; // 打印文档 const printDocument = () => { const url = URL.createObjectURL(outputDoc.value); const printWindow = window.open(url); printWindow.onload = () => { printWindow.print(); }; }; </script>