как отправить файл Excel на электронную почту с помощью модуля nodemailer - PullRequest
0 голосов
/ 31 марта 2019

Я использую модуль 'nodemailer' для отправки файла Excel в виде вложения в электронное письмо.

Примечание. То, что я передаю «содержимому» во вложениях, представляет собой массив объектов.

 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 не может открыть файл 'filename.xlsx', так как формат файла для расширения файла недопустим. Убедитесь, что файл не был поврежден и что расширение файла соответствует формату файлафайл. "

Любая помощь, дорогие участники?

Ответы [ 2 ]

0 голосов
/ 06 апреля 2019

У меня в конечном итоге есть 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;
        }
        }

Счастливое кодирование.

0 голосов
/ 03 апреля 2019

Вы можете указать содержимое в виде простой строки и преобразовать содержимое в формат csv с расширением .csv.

Чтобы преобразовать массив объектов в строку в формате csv, вы можете использовать приведенный ниже код, а затем передать возвращенную строку в sendEmailWithAttachments как content.

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 в настройках Attachemt, используйте contentType свойство

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

Дайте мне знать, если у вас возникнут какие-либо проблемы.

...