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

如何使用Nodemailer发邮件并在Pug渲染的HTML中设置背景图片

核心问题原因
  1. 模板渲染逻辑错误:你当前调用pug.renderFile时传入了空的img、img2参数,此时模板里的#{img}、#{img2}已经被替换为空值,后续再对渲染结果执行pug.compile根本不会生效,cid地址没有被正确填入背景图的url中。
  2. 附件未明确标记为内联资源:背景图附件没有设置contentDisposition: 'inline',Gmail会默认将其识别为普通附件,不会嵌入到邮件内容里。
  3. 邮件客户端兼容性问题:Gmail对div元素的CSSbackground-image属性支持度较差,优先使用table标签的background属性兼容性更好。
修复后的代码

Node.js 代码修改

const nodemailer = require("nodemailer");
const pug = require('pug');
const path = require('path');
const excel = require('../../public/scripts/readExcel');

const image_path = path.join(__dirname, '../../../img/', 'logo.png');
const image_ground_path = path.join(__dirname, '../../../img/', 'backGround.png');
const path_Excel = path.join(__dirname, '../../../config/BD/emails.xlsx');

let dateObj = new Date();
let year = dateObj.getUTCFullYear();

exports.sendEmail = () => {
  try {
    return new Promise((resolve, reject) => {
      let dataExcel = excel.readExcel(path_Excel);
      if (dataExcel.length <= 0) return resolve("No emails sent");

      const transporter = nodemailer.createTransport({
        service: 'gmail',
        host: "smtp.gmail.com",
        port: 587,
        secure: false,
        auth: {
          user: "mygmail@gmail.com",
          pass: "*****"
        },
      });

      // 批量发送处理,避免异步提前resolve
      const sendPromises = dataExcel.map(user => {
        return new Promise((res, rej) => {
          // 直接在renderFile时传入所有参数,无需二次compile
          const html = pug.renderFile(path.join(__dirname, "../../../views/index.pug"), {
            name: user.name,
            img: "cid:logo",
            img2: "cid:backGroundImg",
            year,
            area: user.area
          });

          const mainOptions = {
            from: "mygmail@gmail.com",
            to: user.email, // 替换为你Excel中实际的收件人字段
            subject: "Hello",
            html: html,
            attachments: [
              {
                filename: 'logo-U.png',
                path: image_path,
                cid: 'logo',
                contentDisposition: 'inline',
                contentType: 'image/png'
              },
              {
                filename: 'backGround.png',
                path: image_ground_path,
                cid: 'backGroundImg',
                contentDisposition: 'inline', // 明确标记为内联资源
                contentType: 'image/png'
              }
            ]
          };

          transporter.sendMail(mainOptions, (err, info) => {
            if (err) return rej(err);
            res(info);
          });
        });
      });

      Promise.all(sendPromises)
        .then(() => resolve("Email(s) sent"))
        .catch(err => reject(err.message));
    });
  } catch (error) {
    return Promise.reject(error);
  }
}

Pug 模板修改

优先用table的background属性实现背景,兼容Gmail:

tr
  td
    div(style='background-color:#082CAF;color:white;padding:10px;border-radius:10px 10px 0 0')
      table(width='100%' align='center' cellpadding='0')
        tbody
          tr
            td(width='10%' height='70')
              img(src=img)
            td(width='80%' height='70' style='color:white;text-align:center;font-size:25px')
              strong General Directorate of Services

tr
  td
    div(style='background-color:#ecf0f5;padding:10px;')
      table(width='100%' cellpadding='0' style='margin-top:20px;margin-bottom:40px')
        tbody
          tr
            td(width='10%')
            td(width='60%')
              // 用table嵌套实现背景,兼容性更好
              table(width='100%' cellpadding='40' background=img2 style='border:0.5px solid #e5e5e5;border-radius:2px;background-repeat: no-repeat;background-position:center;background-size: 100% 100%;')
                tr
                  td
                    p(style='font-size:20px;text-align:center;margin:0')
                      strong Dear #{name}.
补充注意事项
  • 不要在style属性里用#{}插值,Pug中动态属性直接写src=img、background=img2即可,避免转义错误
  • 背景图不要超过100KB,尺寸建议控制在1920px宽度以内,避免Gmail拦截
  • 批量发送邮件时不要在for循环里直接resolve Promise,会导致第一个邮件发送成功就直接返回,其余邮件还未发送完成

内容的提问来源于stack exchange,提问作者Jorge Rojas C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:36:06