通过 html 表单使用 nodemailer 发送 PDF 文件

Send a PDF File with nodemailer via a html form

我有一个表单,其中包含上传文件输入。我希望用户能够上传他们的文件并通过表单发送。目前 PDF 文件显示在电子邮件中,但不包含任何数据且无法打开等。

这是我目前在 nodemailer 选项中的内容:

let mailOptions = {
    from: '"Macwear Clothing" <shop@macwearclothing.com>', // sender address
    to: req.body.email, // list of receivers
    subject: 'Order Review', // Subject line
    text: 'Order Acception', // plain text body
    html: output, // html body
    attachments: [{'filename': 'needlesheet.pdf', 'content': req.body.needle, 'contentType': 'application/pdf'
  }]
};

客户端index.ejs文件

<div class="fileUpload up<%= item.number %>" id="m<%= item.number %>">
    <div class="fileUploadContent">
        <h2>Customer:
            <%= item.email %>
        </h2>
        <div class="uploadFile">
            <input id="needle" type="file" name="needle" value="Upload File &gt;">
        </div>
        <form method="POST" action="send" name="sendNeedleSheet" enctype="multipart/form-data">
            <div class="optionalMessage">
                <span>Optional Message:</span>
                <textarea class="customTextArea" name="message"></textarea>
                <input id="email" name="email" type="hidden" value="<%= item.email %>">
            </div>
            <div class="modalOptions">
                <div class="mButton ok">
                    <button class="customButton" type="submit">Send</button>
                 </div>
                <div class="mButton cancel">
                    <span>Cancel</span>
                </div>
           </div>
      </form>
 </div>
 </div>

app.js

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const chalk = require('chalk');
const nodemailer = require('nodemailer');
const multer = require('multer');
const app = express();

//View Engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// Body Parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));

// Set Static Path
app.use(express.static(path.join(__dirname, '/public')));

// Call JSON

//requestLoop();


// var shopifyAPI = require('shopify-node-api');
// var Shopify = new shopifyAPI({
//   shop: 'macwear-clothing-embroidery.myshopify.com', // MYSHOP.myshopify.com
//   shopify_api_key: '', // Your API key
//   access_token: '' // Your API password
// });


var orderData = null;



// Shopify.get('/admin/orders.json', function(err, data, res, headers){
//   app.locals.jsonOrderData = data;
// });

// Shopify.get('/admin/orders/count.json', function(err, data, headers) {
//   app.locals.jsonOrderCount = data;
// });

var requestLoop = setInterval(function () {

  var request = require("request");

  var options_orders = {
    method: 'GET',
    url: 'https://macwear-clothing-embroidery.myshopify.com/admin/orders.json',
    headers: {
      'Postman-Token': '',
      'Cache-Control': 'no-cache',
      Authorization: ''
    }
  };

  var options_order_count = {
    method: 'GET',
    url: 'https://macwear-clothing-embroidery.myshopify.com/admin/orders/count.json',
    headers: {
      'Postman-Token': '',
      'Cache-Control': 'no-cache',
      Authorization: ''
    }
  };


  request(options_orders, function (error, response, body) {
    if (error) throw new Error(error);
    jsonOrderData = JSON.parse(body);
    //console.log(body);
  });

  request(options_order_count, function (error, response, body) {
    if (error) throw new Error(error);
    jsonOrderCount = JSON.parse(body);
    //console.log(body);
  });

}, 60000);


app.get('/shopifycall_order_count', function (req, res) {
  res.send(jsonOrderCount);
  //res.render('dynamic_content');
});

app.get('/shopifycall_orders', function (req, res) {
  res.render('dynamic_content');
});

// Multer File Processing


app.post('/send', (req, res) => {
  const output = `
      <p>Please View & Accpet or Reject the PDF</p>
  `;

let transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 587,
    secure: false, // true for 465, false for other ports
    auth: {
        user: '',
        pass: ''
    },
    tls:{
      rejectUnauthorized:false
    }
});

// setup email data with unicode symbols
let mailOptions = {
    from: '"Macwear Clothing" <shop@macwearclothing.com>', // sender address
    to: req.body.email, // list of receivers
    subject: 'Order Review', // Subject line
    text: 'Order Acception', // plain text body
    html: output, // html body
    attachments: [{'filename': 'needlesheet.pdf', 'content': req.body.needle, 'contentType': 'application/pdf'
  }]
};

// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log(error);
    }
    console.log('Message sent: %s', info.messageId);
    // Preview only available when sending through an Ethereal account
    console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));

    // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
    // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});

console.log(req.body.needle);

});




app.get('/', (req, res) => {
  res.render('index');
});

app.listen(3000, () => {
  console.log('Starting MOS.......');
  console.log(chalk.green('Loaded on port 3000'));
  console.log('Fetching API.......');
  console.log('Initial API Request will take 60 Seconds');
});

我只是使用Multer 来处理文件的上传。只需要设置多个上传目录即可。

var upload = multer({dest: './public/uploads/'});

然后在 /send 路由中添加 upload.single('needle') 并删除箭头函数:

app.post('/send', upload.single('needle'), function (req, res, next) {

});

然后在邮件选项的附件中:

attachments: [
  {
      filename: req.file.originalname,
      path: req.file.path

  }

]

最后,将 HTML 表单上的 enctype 设置为 multipart/form-data 很重要,否则无法通过 multer 上传文件。

您为附件和静态路径都使用了路径,因此文档将不会显示其扩展名

尝试:

app.use(express.static('public'))