Azure Function中NodeJS保存Excel至临时文件夹报错求助
解决Azure Function中Excel文件保存与邮件附件问题
核心问题分析
报错显示%TMP%被当作字符串直接拼接进路径,Node.js不会自动解析环境变量,导致找不到对应目录。同时代码存在异步操作未等待、路径拼接不规范的问题,进一步引发后续邮件发送异常。
分步解决方案
1. 获取正确的临时目录路径
使用Node.js内置的process.env.TEMP(Windows环境)或process.env.TMPDIR(Linux环境)获取Azure Function的临时目录,搭配path模块拼接路径,避免手动拼接的格式错误。
先引入path模块:
const path = require('path');
构建文件路径:
const tempDir = process.env.TEMP || process.env.TMPDIR; const fileName = `workitemquery_${currentdate}.xlsx`; const filePath = path.join(tempDir, fileName);
2. 等待Excel文件写入完成
workbook.xlsx.writeFile是异步操作,必须等待它执行完成后再触发邮件发送,否则会出现文件未生成就读取的情况。将原有的then/catch改为await语法:
try { context.log('creating Excel file'); await workbook.xlsx.writeFile(filePath); context.log('Excel file saved successfully'); } catch (err) { context.log('Error saving Excel file:', err); throw err; // 抛出错误终止流程,避免无效的邮件发送 }
3. 修正Nodemailer的调用逻辑
- 附件路径直接使用上面构建好的
filePath - Nodemailer的
sendMail支持Promise,不要混用await和回调函数,避免语法冲突
修正后的邮件发送代码:
const transporter = nodemailer.createTransport({ host: "{SMTP Server IP address}", port: 50025, secure: false, }); const mailOptions = { to: 'recipient@example.com', // 替换为实际收件人 subject: 'Work Item Query Results', text: 'Please find the attached work item query results.', attachments: [ { filename: fileName, path: filePath } ] }; context.log('Sending email'); try { const info = await transporter.sendMail(mailOptions); context.log('Email sent successfully:', info.response); } catch (error) { context.log('Error sending email:', error.message); }
4. 可选优化:跳过本地文件写入
如果不需要保留本地文件,可直接让ExcelJS生成Buffer,作为邮件附件发送,减少磁盘IO操作:
// 生成Excel文件Buffer const excelBuffer = await workbook.xlsx.writeBuffer(); // 邮件附件改用Buffer attachments: [ { filename: fileName, content: excelBuffer, contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } ]
关键代码片段整合
// 引入必要模块 const path = require('path'); const ExcelJS = require('exceljs'); const { DateTime } = require("luxon"); const nodemailer = require("nodemailer"); // ... 其他业务代码 ... const currentdate = DateTime.now().toFormat('MM-dd-yy'); const tempDir = process.env.TEMP || process.env.TMPDIR; const fileName = `workitemquery_${currentdate}.xlsx`; const filePath = path.join(tempDir, fileName); // 生成并保存Excel文件 try { context.log('creating Excel file'); await workbook.xlsx.writeFile(filePath); context.log('Excel file saved successfully'); } catch (err) { context.log('Error saving Excel file:', err); throw err; } // 发送邮件 const transporter = nodemailer.createTransport({ host: "{SMTP Server IP address}", port: 50025, secure: false, }); const mailOptions = { to: 'your-recipient@example.com', subject: 'Work Item Query Results', text: 'Attached is the latest work item query results.', attachments: [ { filename: fileName, path: filePath } ] }; try { const info = await transporter.sendMail(mailOptions); context.log('Email sent:', info.response); } catch (error) { context.log('Email send error:', error.message); }
内容的提问来源于stack exchange,提问作者mdailey77
相关产品推荐
相关产品推荐

