Electron 按模板导出 Word 并打开

350 阅读2分钟

104105-1734576065241d.jpg 通过 ElectronDocxtemplaterJSZipUtils和系统打印命令实现这一需求。

实现步骤

1. 使用 Docxtemplater 渲染 Word 模板

Docxtemplater 是一个强大的模板引擎,用于填充 Word 模板中的占位符。通过加载模板文件,并结合参数进行渲染,可以快速生成动态 Word 文档。

2. 加载模板

模板文件通过 JSZipUtils.getBinaryContent 加载为二进制内容,随后利用 JSZip 解压缩以供 Docxtemplater 使用。

3. 图像处理(可选)

通过 DocxtemplaterImageModule 插件,可以将图片数据嵌入到 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. 模板渲染

使用 DocxtemplatersetData 方法填充模板变量,并调用 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}"`);