通过
Electron、Docxtemplater、JSZipUtils和系统打印命令实现这一需求。
实现步骤
1. 使用 Docxtemplater 渲染 Word 模板
Docxtemplater 是一个强大的模板引擎,用于填充 Word 模板中的占位符。通过加载模板文件,并结合参数进行渲染,可以快速生成动态 Word 文档。
2. 加载模板
模板文件通过 JSZipUtils.getBinaryContent 加载为二进制内容,随后利用 JSZip 解压缩以供 Docxtemplater 使用。
3. 图像处理(可选)
通过 Docxtemplater 的 ImageModule 插件,可以将图片数据嵌入到 Word 模板中。
4. 保存为临时文件并打开
生成的 Word 文档以 Buffer 格式保存为临时文件,然后利用系统命令打开文件。
核心代码
以下是实现按模板导出 Word 并打开的完整代码:
/**
* 导出 Word 文档到临时文件并打开
* @param {Object} params - 模板数据
* @param {string} inputPath - 模板文件路径
*/
export function exportWordAndOpen(params, inputPath, imgConfig) {
if (!inputPath) throw '请设置模板地址';
// 使用 JSZipUtils 加载模板内容
JSZipUtils.getBinaryContent(inputPath, (error, content) => {
if (error) {
throw error;
}
const imgDataDict = {}; // 图片数据字典
let rendParams = { ...params }; // 渲染参数
// 如果存在图片配置,加入图片数据
if (imgConfig) {
imgDataDict[imgConfig.key] = imgConfig.imgBuffer;
rendParams[imgConfig.key] = imgConfig.key;
}
const zip = new JSZip(content); // 创建 JSZip 实例
const doc = new Docxtemplater(zip, {
paragraphLoop: true,
linebreaks: true,
modules: [
new ImageModule({
getImage: (key) => imgDataDict[key] || '',
getSize: () => [imgConfig.w || 0, imgConfig.h || 0],
}),
],
});
doc.setData(rendParams); // 设置模板变量数据
try {
doc.render(); // 渲染模板
} catch (error) {
console.error('导出模板失败:', error);
throw error;
}
// 生成 Word 文件内容为 Buffer
const buffer = doc
.getZip()
.generate({ type: 'nodebuffer', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
// 保存为临时文件
const tempFilePath = path.join(os.tmpdir(), `export_${Math.random().toString(36).substring(2, 10)}.docx`);
fs.writeFile(tempFilePath, buffer, (writeErr) => {
if (writeErr) {
console.error('保存文件失败:', writeErr);
throw writeErr;
}
console.log(`文件已保存到临时路径: ${tempFilePath}`);
openFileInDefaultProgram(tempFilePath); // 打开文件
});
});
}
/**
* 在系统默认程序中打开文件 (仅限 Windows)
* @param {string} filePath - 文件的路径
*/
export function openFileInDefaultProgram(filePath) {
if (!filePath) throw new Error('文件路径不能为空');
const command = `start "" "${filePath}"`; // Windows 打开文件命令
exec(command, (error) => {
if (error) console.error('文件打开失败:', error);
else console.log('文件已成功打开');
});
}
核心功能解析
1. 模板渲染
使用 Docxtemplater 的 setData 方法填充模板变量,并调用 render 方法生成内容。变量的格式在模板中应以 ${key} 的形式出现。
2. 图像支持
通过 ImageModule 插件,可以动态插入图片。图片以 Buffer 的形式加载,并在模板中占位符对应的字段中显示。
modules: [
new ImageModule({
getImage: (key) => imgDataDict[key] || '',
getSize: () => [imgConfig.w || 0, imgConfig.h || 0],
}),
]
3. 文件保存与打开
保存生成的 Word 文件到系统临时目录,随后使用系统命令打开。
const tempFilePath = path.join(os.tmpdir(), `export_${Math.random().toString(36).substring(2, 10)}.docx`);
fs.writeFile(tempFilePath, buffer, () => openFileInDefaultProgram(tempFilePath));
4. Windows 系统命令
通过 exec 执行 Windows 系统命令 start,自动打开文件。
exec(`start "" "${filePath}"`);