一.按照固定格式导出word文件时,需要先准备一个word模板
二.接下来需要用到一些第三方库
1. docxtemplater
核心作用:Word模板引擎
-
功能特点:
-
解析Word模板中的占位符(如
{name}
、{list}
) -
将数据动态填充到模板的指定位置
-
支持条件判断、循环等逻辑(如
{#list}{/list}
)
-
-
典型应用:
const doc = new Docxtemplater().loadZip(zip); doc.setData({ name: "张三" }); // 填充数据 doc.render(); // 执行渲染
2.
pizzip
(原JSZip)核心作用:ZIP文件处理
-
功能特点:
-
读取/解压Word文档(
.docx
本质是ZIP压缩包) -
修改文档内容后重新打包
-
-
为什么需要:
const zip = new PizZip(content); // 加载.docx二进制内容 doc.getZip().generate(...); // 生成新文档
3.
jszip-utils
核心作用:ZIP文件加载工具
-
解决的问题:
-
提供跨浏览器兼容的方式获取二进制文件(如模板文件)
-
简化AJAX请求二进制内容的过程
-
-
典型用法:
JSZipUtils.getBinaryContent('/template.docx', callback);
4.
file-saver
核心作用:文件下载
-
功能特点:
-
提供
saveAs()
方法触发浏览器下载 -
自动处理不同浏览器的下载兼容性
-
关键代码:
saveAs(blob, "生成的文档.docx"); // 保存为Word文件
三.封装utils文件
在utils文件夹下新建word.js文件
import Docxtemplater from "docxtemplater";
import { saveAs } from "file-saver";
import JSZipUtils from "jszip-utils";
import PizZip from "pizzip";
interface TemplateData {
form: Record<string, unknown>; // 表单数据对象
list?: unknown[]; // 可选列表数据
[key: string]: unknown; // 其他动态属性
}
/**
* 使用Word模板生成并下载文档
* @param data 模板数据对象
* @param fileName 生成的文件名
* @param templatePath 模板路径(默认使用public目录下的template.docx)
*/
export async function downloadWithTemplate(
data: TemplateData,
fileName: string,
templatePath: string = '/template.docx' // 默认从网站根目录public文件夹获取,vue3对应项目public目录,vue2对应src/assets目录
): Promise<void> {
try {
// 1. 异步获取模板文件内容
const content = await new Promise<ArrayBuffer>((resolve, reject) => {
JSZipUtils.getBinaryContent(templatePath, (error, content) => {
if (error) {
reject(new Error(`模板加载失败: ${error.message}`));
return;
}
resolve(content);
});
});
// 2. 创建并加载Zip文档
const zip = new PizZip(content);
const doc = new Docxtemplater().loadZip(zip);
// 3. 设置模板数据
doc.setData({
...data.form, // 展开表单数据
list: data.list, // 列表数据
...data // 其他可能的数据
});
// 4. 渲染文档(尝试)
try {
doc.render();
} catch (renderError) {
throw new Error(`模板渲染错误: ${(renderError as Error)?.message || String(renderError)}`);
}
// 5. 生成并下载Word文档
const out = doc.getZip().generate({
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, fileName);
} catch (error) {
console.error("文档生成失败:", error);
if (error instanceof Error) {
throw new Error(`文档生成过程出错: ${error.message}`);
} else {
throw new Error(`文档生成过程出错: ${String(error)}`);
}
}
}
四.使用
五.效果
模板对比