如何使用nodemailer发送整个文件夹作为邮件附件?
解决方案
nodemailer本身不支持直接将整个文件夹作为单个附件上传,你可以根据需求选择以下两种实现方案:
方案1:遍历文件夹下所有文件,逐个添加为附件
适合文件夹内文件数量不多、总大小未超出邮件服务商附件限制的场景。
你可以用Node.js内置的fs和path模块递归遍历目标文件夹的所有文件,生成符合nodemailer附件要求的数组传入即可。
示例代码:
const nodemailer = require('nodemailer'); const fs = require('fs'); const path = require('path'); // 递归遍历文件夹获取所有文件路径 function getAllFiles(dirPath, arrayOfFiles) { const files = fs.readdirSync(dirPath); arrayOfFiles = arrayOfFiles || []; files.forEach(file => { if (fs.statSync(`${dirPath}/${file}`).isDirectory()) { arrayOfFiles = getAllFiles(`${dirPath}/${file}`, arrayOfFiles); } else { arrayOfFiles.push(path.join(dirPath, "/", file)); } }) return arrayOfFiles; } // 生成附件数组 const targetFolder = 'F:\\你的目标文件夹路径'; // 注意Windows路径反斜杠要转义 const allFiles = getAllFiles(targetFolder); const attachments = allFiles.map(filePath => { return { path: filePath, // 可选:保留文件夹层级作为附件文件名前缀,避免不同子目录下同名文件冲突 filename: path.relative(targetFolder, filePath).replace(/\\/g, '/') } }); // 后续正常调用nodemailer发送即可 const transporter = nodemailer.createTransport({ // 你的邮箱配置,比如smtp服务、端口、账号授权码等 }); transporter.sendMail({ from: '你的发件人邮箱', to: '收件人邮箱', subject: '主题', text: '正文', attachments: attachments // 直接传入生成的附件数组 }, (err, info) => { if(err) console.log(err); else console.log('发送成功', info); });
方案2:先将文件夹压缩为单个压缩包,再发送压缩包
适合文件数量多、需要保留文件夹完整结构的场景,收件人下载后解压即可得到完整文件夹。
你可以用archiver库完成本地压缩,压缩完成后再将压缩包路径作为附件传入nodemailer即可。
示例代码:
const nodemailer = require('nodemailer'); const fs = require('fs'); const archiver = require('archiver'); // 需提前执行`npm i archiver`安装 // 压缩文件夹为zip包 function zipFolder(sourceDir, outputPath) { return new Promise((resolve, reject) => { const output = fs.createWriteStream(outputPath); const archive = archiver('zip', { zlib: { level: 9 } }); // 最高压缩级别 output.on('close', () => resolve(outputPath)); archive.on('error', err => reject(err)); archive.pipe(output); archive.directory(sourceDir, false); // false表示不把源文件夹本身作为根目录放进压缩包,按需调整 archive.finalize(); }) } // 调用示例 const targetFolder = 'F:\\你的目标文件夹路径'; const zipOutputPath = 'F:\\临时存储路径\\folder.zip'; zipFolder(targetFolder, zipOutputPath).then(zipPath => { // 压缩完成后调用nodemailer发送 const transporter = nodemailer.createTransport({ // 你的邮箱配置 }); transporter.sendMail({ from: '你的发件人邮箱', to: '收件人邮箱', subject: '主题', text: '正文', attachments: [ { path: zipPath, filename: '文件夹压缩包.zip' } ] }, (err, info) => { if(err) console.log(err); else { console.log('发送成功', info); // 可选:发送完成后删除本地临时压缩包 fs.unlinkSync(zipPath); } }); }).catch(err => console.log('压缩失败', err));
注意事项
- 两种方案都需要注意总附件大小不要超出你所用的邮箱服务商的附件限制,超出的话会被拒收。
- Windows系统下的文件路径的反斜杠需要转义,或者直接用正斜杠作为路径分隔符。
内容的提问来源于stack exchange,提问作者Speedy
相关产品推荐
相关产品推荐

