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

时间:2019-03-31 13:38:06

标签: node.js nodemailer

我正在使用“ 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 :(得分:0)

您可以将内容指定为纯字符串,然后以.csv作为文件扩展名将内容转换为Also: hudson.remoting.Channel$CallSiteStackTrace: Remote call to JNLP4-connect connection from nobuild01.sdi.pvt/152.144.34.14:50396 at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1741) at hudson.remoting.UserRequest$ExceptionResponse.retrieve(UserRequest.java:357) at hudson.remoting.Channel.call(Channel.java:955) at hudson.FilePath.act(FilePath.java:1036) at hudson.FilePath.act(FilePath.java:1025) at hudson.scm.SubversionSCM.checkout(SubversionSCM.java:928) at hudson.scm.SubversionSCM.checkout(SubversionSCM.java:864) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:113) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:85) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:75) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47) at hudson.security.ACL.impersonate(ACL.java:290) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) java.lang.NoClassDefFoundError: Could not initialize class jenkins.model.Jenkins at hudson.scm.SubversionSCM.descriptor(SubversionSCM.java:2584) at hudson.scm.SubversionSCM.createDefaultSVNOptions(SubversionSCM.java:1085) at hudson.scm.SubversionSCM.createClientManager(SubversionSCM.java:1075) at hudson.scm.SubversionSCM$CheckOutTask.invoke(SubversionSCM.java:1002) at hudson.scm.SubversionSCM$CheckOutTask.invoke(SubversionSCM.java:979) at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2918) at hudson.remoting.UserRequest.perform(UserRequest.java:212) at hudson.remoting.UserRequest.perform(UserRequest.java:54) at hudson.remoting.Request$2.run(Request.java:369) at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at hudson.remoting.Engine$1.lambda$newThread$0(Engine.java:93) at java.lang.Thread.run(Thread.java:745) Caused: java.io.IOException: Remote call on JNLP4-connect connection from nobuild01.sdi.pvt/152.144.219.14:50396 failed at hudson.remoting.Channel.call(Channel.java:961) at hudson.FilePath.act(FilePath.java:1036) Caused: java.io.IOException: remote file operation failed: c:\Dev at hudson.remoting.Channel@4b1b30ed:JNLP4-connect connection from nobuild01.sdi.pvt/152.144.34.14:50396 at hudson.FilePath.act(FilePath.java:1043) at hudson.FilePath.act(FilePath.java:1025) at hudson.scm.SubversionSCM.checkout(SubversionSCM.java:928) at hudson.scm.SubversionSCM.checkout(SubversionSCM.java:864) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:113) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:85) at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:75) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47) at hudson.security.ACL.impersonate(ACL.java:290) at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) 格式。

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

content

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

要在附件设置中指定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));,请使用text/plain属性

contentType

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

答案 1 :(得分:0)

我最终有两种解决方法,都为我工作:

      /*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;
        }
        }

快乐的编码。