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
相关产品推荐
相关产品推荐

