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

如何将React-PDF生成的PDF文件通过Nodemailer添加至邮件附件

解决React客户端生成PDF并通过Nodemailer作为邮件附件发送的问题

问题核心

你当前的代码存在两个关键缺失:

  1. 客户端仅直接下载PDF,未将文件数据传递给后端
  2. 后端Nodemailer配置中缺少附件的实际内容

以下是完整的前后端修改方案:


一、客户端代码修改(生成PDF并传递给后端)

修改generatePDF函数,取消直接下载,先获取PDF的Blob数据,再通过FormData发送到后端接口:

import ReactDOMServer from "react-dom/server";
import html2pdf from "html2pdf.js/dist/html2pdf.min";
import Pdf from "./Pdf";

async function generatePDF(userProfile) {
  const printElement = ReactDOMServer.renderToString(
    Pdf({
      profilepicture: userProfile.profilepicture,
      firstname: userProfile.firstname,
      lastname: userProfile.lastname,
      designation: userProfile.designation,
      email: userProfile.email,
      phonenumber: userProfile.phonenumber,
      summary: userProfile.summary,
      experience: userProfile.experience,
      education: userProfile.education,
      projects: userProfile.projects,
      technologies: userProfile.technologies
    })
  );

  const opt = {
    margin: [15, 0, 30, 0], // top, left, bottom, right
    enableLinks: true,
    filename: "pdfreport",
    html2canvas: { useCORS: true },
    jsPDF: {},
  };

  try {
    const pdf = await html2pdf()
      .from(printElement)
      .set(opt)
      .toPdf()
      .get("pdf");
    
    pdf.setPage(1);
    // 获取PDF的Blob格式数据
    const pdfBlob = pdf.output('blob');
    
    // 构建FormData,包含PDF文件和邮件参数
    const formData = new FormData();
    formData.append('pdfFile', pdfBlob, 'pdfreport.pdf'); // 指定文件名及后缀
    formData.append('send_to', '目标收件人邮箱');
    formData.append('subject', '个人PDF报告');
    formData.append('message', '<p>这是生成的个人PDF报告,请查收</p>');
    formData.append('sent_from', '你的发件人邮箱');
    formData.append('reply_to', '回复邮箱');

    // 发送请求到后端邮件接口
    const response = await fetch('/api/send-email-with-pdf', {
      method: 'POST',
      body: formData
    });

    if (response.ok) {
      console.log('邮件发送成功');
      // 可选:如果需要同时让用户下载PDF,取消下面注释
      // pdf.save();
    } else {
      console.error('邮件发送失败');
    }
  } catch (err) {
    console.error('生成PDF或发送请求出错:', err);
  }
}

export default { generatePDF };

二、后端代码修改(接收PDF并通过Nodemailer发送)

需要先安装multer处理FormData文件上传,再修改邮件发送逻辑:

1. 安装依赖

npm install multer

2. 修改后端代码

import nodemailer from "nodemailer";
import express from 'express';
import multer from 'multer';

const app = express();
// 配置multer为内存存储,直接获取文件buffer
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

const sendEmail = async (subject, message, send_to, sent_from, reply_to, pdfFile) => {
  const transporter = nodemailer.createTransport({
    host: process.env.EMAIL_HOST,
    port: 465,
    secure: true, // 注意这里是布尔值,不是字符串"true"
    auth: {
      user: process.env.EMAIL_USER,
      pass: process.env.EMAIL_PASS,
    },
  });
   
  const options = {
    from: sent_from,
    to: send_to,
    replyTo: reply_to,
    subject: subject,
    html: message,
    attachments: [{
      filename: pdfFile.originalname, // 使用上传时指定的文件名
      content: pdfFile.buffer, // 内存中的PDF文件buffer
      contentType: 'application/pdf' // 指定MIME类型,确保邮件客户端识别为PDF
    }]
  };

  try {
    const info = await transporter.sendMail(options);
    console.log(info);
    return info;
  } catch (err) {
    console.log(err);
    throw err;
  }
};

// 定义接收PDF和邮件参数的接口
app.post('/api/send-email-with-pdf', upload.single('pdfFile'), async (req, res) => {
  try {
    const { subject, message, send_to, sent_from, reply_to } = req.body;
    const pdfFile = req.file;

    if (!pdfFile) {
      return res.status(400).json({ error: '未上传PDF文件' });
    }

    await sendEmail(subject, message, send_to, sent_from, reply_to, pdfFile);
    res.status(200).json({ message: '邮件发送成功' });
  } catch (err) {
    res.status(500).json({ error: '邮件发送失败', details: err.message });
  }
});

export default sendEmail;

三、关键注意事项

  1. 后端Nodemailer配置中secure参数必须是布尔值true,而非字符串
  2. 客户端传递FormData时,需给PDF文件加上.pdf后缀,避免邮件附件格式识别错误
  3. 若需要同时让用户下载PDF,在请求成功后调用pdf.save()即可
  4. 确保后端接口路径与客户端请求路径一致,且已配置CORS(如果前后端跨域)

内容的提问来源于stack exchange,提问作者A.Z.M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:22:02