You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js生成加密PDF并邮件发送时遇文件不存在错误求助

PDF加密后读取报错ENOENT的解决方法

问题根源

你遇到的ENOENT错误,核心原因是异步操作时序不匹配:encrypt函数通过child_process.exec执行加密命令是异步操作,但你在PDF生成完成后调用encrypt就立刻resolve(data),此时加密命令还未执行完毕,目标加密文件还未生成,后续读取自然会提示文件不存在。

解决方案

将encrypt改造为返回Promise的函数,确保加密操作完成后再触发后续的文件读取流程。

修改后的加密函数

const encrypt = function (inputFile, outputFile) {
  return new Promise((resolve, reject) => {
    const exec = require('child_process').exec;
    const ownerPass = 'ownerpasswd';
    const userPass = 'ownerpasswd';
    const cmd = `qpdf --encrypt ${ownerPass} ${userPass} 256 -- ${inputFile} ${outputFile}`;

    exec(cmd, function (err) {
      if (err) {
        console.error("PDF加密失败", err, err.stack);
        reject(err);
      } else {
        console.log("PDF加密完成");
        resolve(outputFile);
      }
    });
  });
};

修改PDF生成流程,等待加密完成

pdf.create(htmlString, {format: 'A4', timeout: 600000})
  .toFile(filePath, function (err, data) {
    if (err) {
      logger.error('生成PDF文件出错::->', err.stack);
      return reject(err);
    } else {
      logger.info('PDF已成功生成到tmp目录');
      const encryptedFilePath = '/tmp/' + _.get(lead, 'code', '00003') + '_receipt_encrypted.pdf';
      // 等待加密完成后再执行后续流程
      encrypt(filePath, encryptedFilePath)
        .then(() => {
          resolve({...data, encryptedFilePath});
        })
        .catch(encryptErr => {
          logger.error('加密PDF出错::->', encryptErr.stack);
          reject(encryptErr);
        });
    }
  });

额外检查点

  • 确认lead.code的取值是否正确,避免文件名拼接错误导致路径无效
  • 在加密完成的回调中打印encryptedFilePath,验证文件是否确实生成在指定路径
  • 读取文件时确保使用绝对路径,避免相对路径导致的寻址错误

内容的提问来源于stack exchange,提问作者Aakarshit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:31:05