如何使用 nodemailer 模块将 Excel 文件发送到电子邮件

how to send an Excel file to an email using nodemailer module

我正在使用 'nodemailer' 模块将 Excel 文件作为电子邮件的附件发送。

注意:我在附件中传递给 'content' 的是一组对象。

 function sendEmailWithAttachments(recipientEmailId, subject, content, next) {

        var ormMailerInfo = getORMMailerInfo();
        var transporter = nodemailer.createTransport(smtpTransport({
            host: ormMailerInfo.orm_mailer_host,
            secure: ormMailerInfo.orm_mailer_secure,
            port: ormMailerInfo.orm_mailer_port,
            auth: {
                user: ormMailerInfo.orm_mailer_user,
                pass: ormMailerInfo.orm_mailer_pass
            }
        }));

        transporter.sendMail({
            from: ormMailerInfo.orm_mailer_user,
            to: recipientEmailId,
            subject: subject,
            attachments: [
                {   /* the uniqueness of my question begins from here */
                    // file being sent is Excel file as '.xlsx' indicates
                    filename: subject + '.xlsx',
                    // content/data being sent an array of objects
                    content: new Buffer(content,'utf-8')
                }
                ]
        }, next);
    }

我已成功发送和接收,但是当打开excel文件时,它显示如下错误:

"Excel cannot open the file 'filename.xlsx' because the file format for the file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."

亲爱的会员,有什么帮助吗?

您可以将内容指定为纯字符串,并将内容转换为 csv 格式,文件扩展名为 .csv。

要将对象数组转换为 csv 格式的字符串,您可以使用以下代码,然后将返回的字符串作为 content.

传递给您的 sendEmailWithAttachments

var isArray = Array.isArray
  , keys = Object.keys;

CSV.CHAR_RETURN = 0xd;
CSV.CHAR_NEWLINE = 0xa;
CSV.DELIMITER = 0x2c;
CSV.CHAR_ENCAPSULATE = 0x22;

function head (a) {
  return a[0];
}

function tail (a) {
  return a[a.length -1];
}

function char (c) {
  return 'number' === typeof c
    ? String.fromCharCode.apply(null, arguments)
    : c;
}

function needsEncapsulation (string) {
  return !!string && (
          string.toString().indexOf(char(CSV.DELIMITER)) >= 0 ||
          string.toString().indexOf(char(CSV.CHAR_RETURN)) >= 0 ||
          string.toString().indexOf(char(CSV.CHAR_NEWLINE)) >= 0 ||
          string.toString().indexOf(char(CSV.CHAR_ENCAPSULATE)) >= 0
        );
}

function encapsulate (string) {
  var wrapperChar = char(CSV.CHAR_ENCAPSULATE)
    , replaceWith = "\" + char(CSV.CHAR_ENCAPSULATE)
    , escapedValue = string.toString().replace(new RegExp(wrapperChar, 'g'), replaceWith);

  return wrapperChar + escapedValue + wrapperChar;
}

/**
 * Parses an array of objects to a CSV output
 */

// try { module.exports = CSV; } catch(e) {}
function CSV (objects, opts) {
  if ('object' !== typeof objects) throw new TypeError("expecting an array");

  opts = 'object' === typeof opts
    ? opts
    : {};

    objects = isArray(objects)
      ? objects.slice()
      : [objects];

      if (!objects.length) throw new Error("expecting at least one object");

      var headers = keys(head(objects))
        , buf = [];

      while (objects.length) {
        var lbuf = []
          , object = objects.shift();

        for (var i = 0 ;i < headers.length; ++i) {
          var header = headers[i];

          if (lbuf.length) lbuf.push(char(CSV.DELIMITER));
          object[header] = needsEncapsulation(object[header])
            ? encapsulate(object[header])
            : object[header];

            lbuf.push(object[header]);
        }

        buf.push(lbuf.join(''));
        buf.push(char(CSV.CHAR_RETURN, CSV.CHAR_NEWLINE));
      }

      return false !== opts.headers
        ? [].concat(headers.join(char(CSV.DELIMITER)), char(CSV.CHAR_NEWLINE)).concat(buf).filter(Boolean).join('')
        : buf.filter(Boolean).join('');
}


var data = [];
 
for (var i = 0; i < 10; ++i) {
    data.push({ 
        id: Math.random().toString(16).slice(2), 
        value: data.length % 2 
    });
}
 
console.log(CSV(data));

以上代码取自to-csv模块。

要在附件设置中指定 text/plain 使用 contentType 属性

attachments: [
  {   
    filename: 'youfile_name.csv',
    content: yourContent,
    contentType: 'text/plain'
  }
]

如果您遇到任何问题,请告诉我。

我最终找到了 2 种方法来解决这个问题,并且都对我有用:

      /*1. using `to-csv` module -> `npm i to-csv`*/
      var toCsv = require('to-csv');
      attachments: [{filename: subject + '.csv',content: toCsv(content)}]

     or

     /* 2. using `json2csv` module -> npm i json2csv*/
     attachments: [{filename: subject + '.csv',content:json2csv(content)}]

       function json2csv(content){
       const { Parser } = require('json2csv');
       var fields = getFields(content);
       return new Parser({ fields }).parse(content);

       function getFields(content){
            var fields = [];
            for(var i = 0; i < content.length; i++){
                fields = Object.keys(content[i]);
                if(fields.length > 0)
                    break;
            };
            return fields;
        }
        }

编码愉快。