精华内容
下载资源
问答
  • C# MailMessage 写的邮件发送程序,在添加某些包含中文字符的附件时,收件人处附件显示不出来。但有的附件能显示。附上添加附件的代码,后面的图片是收件人附件的显示,附件打不开。 [img=...
  • ANDROID带附件的后台邮件发送可以配置邮件的主题邮件正文和邮件附件供参考.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 网上有很多python发送邮件的方法参考,但基本都无法防止乱码现象的发生,今天在写自动化脚本的时候遇到了这个问题,在此处记录一下,希望能对大家有所帮助! 乱码现象 首先我们来看我最开始写的python发送邮件的...

    目录

     

    摘要

    乱码现象

    解决办法


    摘要

    网上有很多python发送邮件的方法参考,但基本都无法防止乱码现象的发生,今天在写自动化脚本的时候遇到了这个问题,在此处记录一下,希望能对大家有所帮助!

    乱码现象

    首先我们来看我最开始写的python发送邮件的代码,如下所示:

    # coding=utf-8
    import os
    import xlwt
    
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email import encoders
    
    
    def sendMail(self):
        # 收件人(列表)
        mail_receivers=['xxxx@qq.com']
        # 邮件标签
        mail_lable="测试邮件"
        # 使用的邮箱的smtp服务器地址,这里是qq的
        mail_host="smtp.qq.com"
        # 用户名,登录名
        mail_user="xxxx@qq.com"
        # 授权码,注意这里不是密码是授权码
        mail_pass="xxxx"
        # 邮箱的后缀
        mail_postfix="qq.com"
    
        files = ['D:/中文测试.xlsx']
        me=mail_lable+"<"+mail_user+"@"+mail_postfix+">"
        msg = MIMEMultipart()
        msg.attach(MIMEText('正文',_subtype='html', _charset='utf-8'))
        msg['Subject'] = '标题'
        msg['From'] = me
        msg['To'] = ",".join(mail_receivers)                #将收件人列表以‘,’分隔
        #print(len(files))
        if len(files) != 0:
            for i in range(len(files)):
    
                if os.path.isfile(files[i]):
                    att = MIMEBase('application', 'octet-stream')
                    att.set_payload(open(files[i], 'rb').read())
                    att.add_header('Content-Disposition', 'attachment', filename=os.path.basename(files[i])) 
                    encoders.encode_base64(att)
                    msg.attach(att)
    
        try:
            server = smtplib.SMTP_SSL(mail_host, 465)
            server.login(mail_user,mail_pass)                    #登录操作
            server.sendmail(me, mail_receivers, msg.as_string())
            server.close()
        except Exception as e:
            return False
        return True
    if __name__ == '__main__':
       sendMail()

    qq邮箱申请授权码方法如下:

    点击设置——》账户:

    下拉,把这一栏全部开启,然后点击生成授权码即可。

    代码比较简单,遍历文件列表,加入到msg对象中,最后以附件的形式发送到邮箱,这里我使用的是自己的邮箱,给自己发送信息,调用sendMail方法运行,本来以为完事了,结果附件名称却显示乱码,于是开始寻找解决之道。

    解决办法

    最后经过各种尝试,查阅资料等,找到了一种确实可行的方法,修改以下代码即可:

    att.add_header('Content-Disposition', 'attachment', filename=('gbk', '', os.path.basename(files[i])) )

    这之后乱码问题就被解决了。后来发现windows平台下使用gbk没有问题,改成utf-8的话网页没有问题,但是手机端会乱码。再后来我用同事的电脑进行尝试,发现他的电脑不需要修改代码也不会有乱码问题的出现,修改了本行代码也不会有问题。。。

    总而言之,这样不会出现问题就好,希望能对正在观看的你有所帮助,喜欢还请右上角点个赞哦,谢谢!

    展开全文
  • 经测试,好像单用户发送没问题附件没问题,多用户发送只有第一个用户能正常打开附件。(PS格式,不完美) 2018/07/27 最终解决了多用户发问题,原程序有几个小问题,更新! 发邮件进程: CREATE OR REPLACE ...

    原文地址:https://blog.csdn.net/zhanzhib/article/details/42292455

    经测试,好像单用户发送没问题附件没问题,多用户发送只有第一个用户能正常打开附件。(PS格式,不完美)

    2018/07/27 最终解决了多用户发问题,原程序有几个小问题,更新!

    发邮件进程:

    CREATE OR REPLACE Procedure NI_TEST_EMAIL(P_TXT Varchar2,
                                                P_SUB Varchar2,
                                                P_SENDOR Varchar2,
                                                P_RECEIVER Varchar2,
                                                P_SERVER Varchar2,
                                                P_PORT Number Default 25,
                                                P_NEED_SMTP Int Default 0,
                                                P_USER Varchar2 Default Null,
                                                P_PASS Varchar2 Default Null,
                                                P_FILENAME Varchar2 Default Null,
                                                P_ENCODE Varchar2 Default 'bit 7')
         Authid Current_User Is
         /*
         作用:用oracle发送邮件
         主要功能:1、支持多收件人。
                   2、支持中文
                   3、支持抄送人
                   4、支持大于32K的附件
                   5、支持多行正文
                   6、支持多附件
                   7、支持文本附件和二进制附件
                   8、支持HTML格式
    
         参数说明:
                   p_txt :邮件正文
                   p_sub: 邮件标题
                   p_SendorAddress : 发送人邮件地址
                   p_ReceiverAddress : 接收地址,可以同时发送到多个地址上,地址之间用","或者";"隔开
                   p_EmailServer : 邮件服务器地址,可以是域名或者IP
                   p_Port :邮件服务器端口
                   p_need_smtp:是否需要smtp认证,0表示不需要,1表示需要
                   p_user:smtp验证需要的用户名
                   p_pass:smtp验证需要的密码
                   p_filename:附件名称,必须包含完整的路径,如"d:\temp\a.txt"。
                               可以有多个附件,附件名称只见用逗号或者分号分隔
                   p_encode:附件编码转换格式,其中 p_encode='bit 7' 表示文本类型附件
                                                    p_encode='base64' 表示二进制类型附件
    
         注意:
               1、对于文本类型的附件,不能用base64的方式发送,否则出错
               2、对于多个附件只能用同一种格式发送
         */
         L_CRLF Varchar2(2) := UTL_TCP.CRLF;
         L_SENDORADDRESS Varchar2(4000);
         L_SPLITE Varchar2(10) := '++';
         BOUNDARY Constant Varchar2(256) := '-----By ERP';
         FIRST_BOUNDARY Constant Varchar2(256) := '--' || BOUNDARY || L_CRLF;
         LAST_BOUNDARY Constant Varchar2(256) := '--' || BOUNDARY || '--' || L_CRLF;
    		 --2018/07/27 增加charset=gb2312; 解决部分系统标题乱码
         MULTIPART_MIME_TYPE Constant Varchar2(256) := 'multipart/mixed; charset=gb2312;boundary="' ||BOUNDARY || '"';
         /* 以下部分是发送大二进制附件时用到的变量 */
         L_FIL Bfile;
         L_FILE_LEN Number;
         --L_MODULO Number;
         L_PIECES Number;
         L_FILE_HANDLE UTL_FILE.FILE_TYPE;
    		 --2018/07/27 屏蔽员 L_AMT:=672 * 3的赋值,是不能多用户发送的元凶,再写附件时初始化
         L_AMT Binary_Integer; /* ensures proper format;  2016 */ 
         L_FILEPOS Pls_Integer := 1; /* pointer for the file */
         --L_CHUNKS Number;
         L_BUF Raw(2100);
         L_DATA Raw(2100);
         --L_MAX_LINE_WIDTH Number := 54;
         L_DIRECTORY_BASE_NAME Varchar2(100) := 'DIR_FOR_SEND_MAIL';--此环境变量不存在的
         L_LINE Varchar2(1000);
         L_MESG Varchar2(32767);
         /* 以上部分是发送大二进制附件时用到的变量 */
         Type ADDRESS_LIST Is Table Of Varchar2(100) Index By Binary_Integer;
         MY_ADDRESS_LIST ADDRESS_LIST;
         Type ACCT_LIST Is Table Of Varchar2(100) Index By Binary_Integer;
         MY_ACCT_LIST ACCT_LIST;
         -------------------------------------返回附件源文件所在目录或者名称--------------------------------------
         Function GET_FILE(P_FILE Varchar2, P_GET Int) Return Varchar2 Is
              --p_get=1 表示返回目录
              --p_get=2 表示返回文件名
              L_FILE Varchar2(1000);
         Begin
              If INSTR(P_FILE, '\') > 0 Then
                   --windows
                   If P_GET = 1 Then
                        L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '\', -1) - 1);
                   Elsif P_GET = 2 Then
                        L_FILE := SUBSTR(P_FILE,
                                         - (LENGTH(P_FILE) -
                                           INSTR(P_FILE, '\', -1)));
                   End If;
              Elsif INSTR(P_FILE, '/') > 0 Then
                   --linux/unix
                   If P_GET = 1 Then
                        L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '/', -1) - 1);
                   Elsif P_GET = 2 Then
                        L_FILE := SUBSTR(P_FILE,
                                         - (LENGTH(P_FILE) -
                                           INSTR(P_FILE, '/', -1)));
                   End If;
              End If;
              Return L_FILE;
         End;
    
         ---------------------------------------------删除directory------------------------------------
         Procedure DROP_DIRECTORY(P_DIRECTORY_NAME Varchar2) Is
         Begin
              Execute Immediate 'drop directory ' || P_DIRECTORY_NAME;
         Exception
              When Others Then
                   Null;
         End;
    
         --------------------------------------------------创建directory-----------------------------------------
         Procedure CREATE_DIRECTORY(P_DIRECTORY_NAME Varchar2, P_DIR Varchar2) Is
         Begin
              Execute Immediate 'create directory ' || P_DIRECTORY_NAME ||
                                ' as ''' || P_DIR || '''';
              Execute Immediate 'grant read,write on directory ' ||
                                P_DIRECTORY_NAME || ' to public';
         Exception
              When Others Then
                   Raise;
         End;
    
         --------------------------------------------分割邮件地址或者附件地址-----------------------------------
         Procedure P_SPLITE_STR(P_STR Varchar2, P_SPLITE_FLAG Int Default 1) Is
              L_ADDR Varchar2(254) := '';
              L_LEN Int;
              L_STR Varchar2(4000);
              J Int := 0; --表示邮件地址或者附件的个数
         Begin
              /*处理接收邮件地址列表,包括去空格、将;转换为,等*/
              L_STR := Trim(RTRIM(Replace(Replace(P_STR, ';', ','), ' ', ''), ','));
              L_LEN := LENGTH(L_STR);
              For I In 1 .. L_LEN Loop
                   If SUBSTR(L_STR, I, 1) <> ',' Then
                        L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1);
                   Else
                        J := J + 1;
                        If P_SPLITE_FLAG = 1 Then
                             --表示处理邮件地址
                             --前后需要加上'<>',否则很多邮箱将不能发送邮件
                             L_ADDR := '<' || L_ADDR || '>';
                             --调用邮件发送过程
                             MY_ADDRESS_LIST(J) := L_ADDR;
                        Elsif P_SPLITE_FLAG = 2 Then
                             --表示处理附件名称
                             MY_ACCT_LIST(J) := L_ADDR;
                        End If;
                        L_ADDR := '';
                   End If;
                   If I = L_LEN Then
                        J := J + 1;
                        If P_SPLITE_FLAG = 1 Then
                             --调用邮件发送过程
                             L_ADDR := '<' || L_ADDR || '>';
                             MY_ADDRESS_LIST(J) := L_ADDR;
                        Elsif P_SPLITE_FLAG = 2 Then
                             MY_ACCT_LIST(J) := L_ADDR;
                        End If;
                   End If;
              End Loop;
         End;
    
         ------------------------------------------------写邮件头和邮件内容------------------------------------------
         Procedure WRITE_DATA(P_CONN In Out Nocopy UTL_SMTP.CONNECTION,
                              P_NAME In Varchar2,
                              P_VALUE In Varchar2,
                              P_SPLITE Varchar2 Default ':',
                              P_CRLF Varchar2 Default L_CRLF) Is
         Begin
              /* utl_raw.cast_to_raw 对解决中文乱码问题很重要*/
              UTL_SMTP.WRITE_RAW_DATA(P_CONN,
                                      UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME ||
                                                                  P_SPLITE ||
                                                                  P_VALUE ||
                                                                  P_CRLF,
                                                                  'ZHS16GBK')));
         End;
    
         ----------------------------------------写MIME邮件尾部-----------------------------------------------------
         Procedure END_BOUNDARY(CONN In Out Nocopy UTL_SMTP.CONNECTION,
                                Last In Boolean Default False) Is
         Begin
              UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
              If (Last) Then
                   UTL_SMTP.WRITE_DATA(CONN, LAST_BOUNDARY);
              End If;
         End;
    
         ----------------------------------------------发送附件----------------------------------------------------
         Procedure ATTACHMENT(CONN In Out Nocopy UTL_SMTP.CONNECTION,
                              MIME_TYPE In Varchar2 Default 'text/plain',
                              INLINE In Boolean Default True,
                              FILENAME In Varchar2 Default 't.txt',
                              TRANSFER_ENC In Varchar2 Default '7 bit',
                              DT_NAME In Varchar2 Default '0') Is
              L_FILENAME Varchar2(1000);
         Begin
              --写附件头
              UTL_SMTP.WRITE_DATA(CONN, FIRST_BOUNDARY);
              --设置附件格式
              WRITE_DATA(CONN, 'Content-Type', MIME_TYPE);
              --如果文件名称非空,表示有附件
              DROP_DIRECTORY(DT_NAME);
              --创建directory
              CREATE_DIRECTORY(DT_NAME, GET_FILE(FILENAME, 1));
              --得到附件文件名称
              L_FILENAME := GET_FILE(FILENAME, 2);
              If (INLINE) Then
                   WRITE_DATA(CONN,
                              'Content-Disposition',
                              'inline; filename="' || L_FILENAME || '"');
              Else
                   WRITE_DATA(CONN,
                              'Content-Disposition',
                              'attachment; filename="' || L_FILENAME || '"');
              End If;
              --设置附件的转换格式
              If (TRANSFER_ENC Is Not Null) Then
                   WRITE_DATA(CONN, 'Content-Transfer-Encoding', TRANSFER_ENC);
              End If;
              UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
              --begin 贴附件内容
              If TRANSFER_ENC = 'bit 7' Then
                   --如果是文本类型的附件
                   Begin
                        L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME,
                                                        L_FILENAME,
                                                        'r'); --打开文件
                        --把附件分成多份,这样可以发送超过32K的附件
                        Loop
                             UTL_FILE.GET_LINE(L_FILE_HANDLE, L_LINE);
                             L_MESG := L_LINE || L_CRLF;
                             WRITE_DATA(CONN, '', L_MESG, '', '');
                        End Loop;
                        UTL_FILE.FCLOSE(L_FILE_HANDLE);
                        END_BOUNDARY(CONN);
                   Exception
                        When Others Then
                             UTL_FILE.FCLOSE(L_FILE_HANDLE);
                             END_BOUNDARY(CONN);
                             Null;
                   End; --结束文本类型附件的处理
              Elsif TRANSFER_ENC = 'base64' Then
                   --如果是二进制类型的附件
                   Begin
                        L_AMT := 672 * 3;----2018/07/27 增加 初始化
                        --把附件分成多份,这样可以发送超过32K的附件
                        L_FILEPOS := 1; --重置offset,在发送多个附件时,必须重置
                        L_FIL := BFILENAME(DT_NAME, L_FILENAME);
                        L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);
                        --L_MODULO := Mod(L_FILE_LEN, L_AMT);
                        L_PIECES := Ceil(L_FILE_LEN / L_AMT);--2018/07/26 附件打不开修改 TRUNC(L_FILE_LEN / L_AMT);
                       /* If (L_MODULO <> 0) Then
                             L_PIECES := L_PIECES + 1;
                        End If;*/
                        DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY);
                        DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
                        L_DATA := Null;
                        For I In 1 .. L_PIECES Loop
                             L_FILEPOS := I * L_AMT + 1;
                             L_FILE_LEN := L_FILE_LEN - L_AMT;
                             L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF);
                             /*L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) /L_MAX_LINE_WIDTH);
                             If (I <> L_PIECES) Then
                                  L_CHUNKS := L_CHUNKS - 1;
                             End If;*/
                             UTL_SMTP.WRITE_RAW_DATA(CONN,UTL_ENCODE.BASE64_ENCODE(L_DATA));
                             L_DATA := Null;
                             If (L_FILE_LEN < L_AMT And L_FILE_LEN > 0) Then
                                  L_AMT := L_FILE_LEN;
                             End If;
                             DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
                        End Loop;
                        DBMS_LOB.FILECLOSE(L_FIL);
                        END_BOUNDARY(CONN);
                   Exception
                        When Others Then
                             DBMS_LOB.FILECLOSE(L_FIL);
                             END_BOUNDARY(CONN);
                             Raise;
                   End; --结束处理二进制附件
              End If; --结束处理附件内容
              DROP_DIRECTORY(DT_NAME);
         End; --结束过程ATTACHMENT
         ---------------------------------------------真正发送邮件的过程--------------------------------------------
         Procedure P_EMAIL(P_SENDORADDRESS2 Varchar2, --发送地址
                           P_RECEIVERADDRESS2 Varchar2) --接受地址
          Is
              L_CONN UTL_SMTP.CONNECTION; --定义连接
         Begin
              /*初始化邮件服务器信息,连接邮件服务器*/
              L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER, P_PORT);
              --使用UTL_SMTP.HELO有可能会提示“ORA-29279: SMTP 永久性错误: 503 5.5.2 Send hello first.”
              --改成使用UTL_SMTP.EHLO就好了
              --UTL_SMTP.HELO(L_CONN, P_SERVER);
              UTL_SMTP.EHLO(L_CONN, P_SERVER);
              /* smtp服务器登录校验 */
              If P_NEED_SMTP = 1 Then
                   UTL_SMTP.COMMAND(L_CONN, 'AUTH LOGIN', '');
                   UTL_SMTP.COMMAND(L_CONN,
                                    UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER))));
                   UTL_SMTP.COMMAND(L_CONN,
                                    UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS))));
              End If;
              /*设置发送地址和接收地址*/
              UTL_SMTP.MAIL(L_CONN, P_SENDORADDRESS2);
              UTL_SMTP.RCPT(L_CONN, P_RECEIVERADDRESS2);
              /*设置邮件头*/
              UTL_SMTP.OPEN_DATA(L_CONN);
              --2018/07/26 WRITE_DATA(L_CONN,'Date',TO_CHAR(Sysdate, 'yyyy-mm-dd hh24:mi:ss'));
              /*设置发送人*/
              WRITE_DATA(L_CONN, 'From', P_SENDOR);
              /*设置接收人*/
              WRITE_DATA(L_CONN, 'To', P_RECEIVER);
              /*设置邮件主题*/
              WRITE_DATA(L_CONN, 'Subject', P_SUB);
              WRITE_DATA(L_CONN, 'Content-Type', MULTIPART_MIME_TYPE);
              UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
              UTL_SMTP.WRITE_DATA(L_CONN, FIRST_BOUNDARY);
              WRITE_DATA(L_CONN, 'Content-Type', 'text/plain;charset=gb2312');
              --单独空一行,否则,正文内容不显示
              UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
              /* 设置邮件正文
              把分隔符还原成chr(10)。这主要是为了shell中调用该过程,如果有多行,则先把多行的内容合并成一行,并用 l_splite分隔
              然后用 l_crlf替换chr(10)。这一步是必须的,否则将不能发送邮件正文有多行的邮件
              */
              WRITE_DATA(L_CONN, '',Replace(Replace(P_TXT, L_SPLITE, CHR(10)),CHR(10),L_CRLF),'','');
              END_BOUNDARY(L_CONN);
              --如果文件名称不为空,则发送附件
              If (P_FILENAME Is Not Null) Then
                   --根据逗号或者分号拆分附件地址
                   P_SPLITE_STR(P_FILENAME, 2);
                   --循环发送附件(在同一个邮件中)
                   For K In 1 .. MY_ACCT_LIST.COUNT Loop
                        ATTACHMENT(CONN => L_CONN,
                                   INLINE => false,
                                   FILENAME => MY_ACCT_LIST(K),
                                   TRANSFER_ENC => P_ENCODE,
                                   DT_NAME => L_DIRECTORY_BASE_NAME ||TO_CHAR(K));
                   End Loop;
              End If;
              /*关闭数据写入*/
              UTL_SMTP.CLOSE_DATA(L_CONN);
              /*关闭连接*/
              UTL_SMTP.QUIT(L_CONN);
              /*异常处理*/
         Exception
              When Others Then
                   Null;
                   Raise;
         End;
    
         ---------------------------------------------------主过程-----------------------------------------------------
    Begin
         L_SENDORADDRESS := '<' || P_SENDOR || '>';
         P_SPLITE_STR(P_RECEIVER); --处理邮件地址
         For K In 1 .. MY_ADDRESS_LIST.COUNT Loop
              P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K));
         End Loop;
         /*处理邮件地址,根据逗号分割邮件*/
    Exception
         When Others Then
              Raise;
    End;
    

    报表附件发送前修改后缀,原报表后缀是.out,修改为.ps(.xls也可以)

    Declare
         p_Request_Id Number := 19779753;--报表ID
         v_email_address Varchar2(200) := 'email@email.com';
         Cursor c Is
              Select a.Request_Id       Request_Id,
                     b.Outfile_Name     Outfile_Name,
                     a.Status_Code      Status_Code,
                     a.Phase_Code       Phase_Code,
                     b.Output_File_Type,
                     a.Program
                From Fnd_Conc_Req_Summary_v a, Fnd_Concurrent_Requests b
               Where a.Request_Id = b.Request_Id
                     And a.Request_Id = p_Request_Id
                     And a.Phase_Code = 'C'
                     And a.Status_Code = 'C'
                     And b.Outfile_Name Is Not Null;
       
         ln_last_split   Number;
         v_src_location  Varchar2(300);
         v_file_name     Varchar2(100);
         v_dest_filename Varchar2(100);
    Begin
         For C1 In c Loop
              ln_last_split := instr(C1.Outfile_Name, '/', -1, 1);
              --原名
              v_file_name := substr(C1.Outfile_Name, ln_last_split + 1);
              --转名后(改ps后缀)
              v_dest_filename := substr(v_file_name,1,instr(v_file_name, '.', -1, 1) ) ||'ps';
              --最终文件路径
              v_src_location := substr(C1.Outfile_Name, 1, ln_last_split) || v_dest_filename;
              utl_file.fcopy('REPORT_DIR', --(需手动创建)环境变量路径 create directory REPORT_DIR as 路径地址; 
                             v_file_name, --原文件名
                             'REPORT_DIR', --(需手动创建)环境变量路径 create directory REPORT_DIR as 路径地址;
                             v_dest_filename --拷贝后文件名
                             );
              NI_TEST_EMAIL(C1.program || 'output file',
                            C1.program,
                            'ERP-email@email.com',
                            v_email_address,
                            'smtp1.email.com',
                            25,
                            0,
                            Null,
                            Null,
                            v_src_location,
                            'base64');
         End Loop;
    End;
    

    (此问题已解决,保留当其他方式)同时发给多个EMAIL用户,附件有打不开的情况,分拆成单个发送又没问题。

    分拆方法,下文中出现ni_app_ext.split()代码:

    --先创建数组
    CREATE OR REPLACE TYPE NI_STR_ARRAY is VARRAY(10000) OF VARCHAR2(500)
    --分拆函数
    Function Split(v_source Varchar2, v_delimiter Varchar2 Default ',')
         Return NI_STR_ARRAY Is
         l_DelLen Number;
         l_Pos    Number;
         l_Start  Number;
         l_Length Number;
         l_holder Varchar2(200);
         l_Array NI_STR_ARRAY := ni_str_array();
    Begin
         --Check for NULL
         If v_source Is Null
            Or v_delimiter Is Null Then
              l_Array.Extend;
              l_Array(l_Array.Count) := '';
              Return l_Array;
         End If;
         --Get the length of the delimeter
         l_DelLen := Length(v_Delimiter);
         l_Pos := instr(Upper(v_source), Upper(v_Delimiter));
         --Only one entry was found
         If l_Pos = 0 Then
              l_Array.extend;
              l_Array(l_Array.Count) := v_source;
              Return l_Array;
         End If;
         --More than one entry was found - loop to get all of them
         l_Start := 1;
         While l_Pos > 0 Loop
              --Set current entry
              l_Length := l_Pos - l_Start;
              l_holder := substr(v_source, l_start, l_length);
              -- Update array and counter
              l_Array.extend;
              l_Array(l_Array.Count) := l_holder;
              --Set the new starting position
              l_Start := l_Pos + l_DelLen;
              l_Pos := instr(Upper(v_source), Upper(v_Delimiter), l_Start);
         End Loop;
         --Set last entry
         l_holder := substr(v_source, l_start, Length(v_source));
         -- Update array and counter if necessary
         If Length(l_holder) > 0 Then
              l_Array.extend;
              l_Array(l_Array.Count) := l_holder;
         End If;
         --Return the number of entries found
         Return l_Array;
    End;

    循环分拆发送:

    Declare
         p_Request_Id Number := 19781729;
         v_email_address Varchar2(1000) := '1@email.com;2@email.com;3@email.com';
         Cursor c Is
              Select a.Request_Id       Request_Id,
                     b.Outfile_Name     Outfile_Name,
                     a.Status_Code      Status_Code,
                     a.Phase_Code       Phase_Code,
                     b.Output_File_Type,
                     a.Program
                From Fnd_Conc_Req_Summary_v a, Fnd_Concurrent_Requests b
               Where a.Request_Id = b.Request_Id
                     And a.Request_Id = p_Request_Id
                     And a.Phase_Code = 'C'
                     And a.Status_Code = 'C'
                     And b.Outfile_Name Is Not Null;
         
         ln_last_split   Number;
         v_src_location  Varchar2(300);
         v_file_name     Varchar2(100);
         v_dest_filename Varchar2(100);
         v_one_email Varchar2(100);
    Begin
         For C1 In c Loop
              ln_last_split := instr(C1.Outfile_Name, '/', -1, 1);
              --原名
              v_file_name := substr(C1.Outfile_Name, ln_last_split + 1);
              --转名后(改ps后缀)
              v_dest_filename := substr(v_file_name,1,instr(v_file_name, '.', -1, 1) ) ||'xls';
              --最终文件路径
              v_src_location := substr(C1.Outfile_Name, 1, ln_last_split) || v_dest_filename;
              utl_file.fcopy('REPORT_DIR', --环境变量路径 DIRECTORY_NAME
                             v_file_name, --原文件名
                             'REPORT_DIR', --环境变量路径 DIRECTORY_NAME
                             v_dest_filename --拷贝后文件名
                             );
              --循环发邮件开始
              For i In 1 .. ni_app_ext.split(v_email_address,';').count Loop
                v_one_email:=null;
                v_one_email:=ni_app_ext.split(v_email_address, ';') (i);
                If v_one_email Is Not Null Then
                  NI_TEST_EMAIL(C1.program || '附件!'||chr(10)||'如出现无法打开现象,请自行到ERP中获取,报表ID:'||p_Request_Id,
                                C1.program,
                                'ERP-ConreqMailer@email.com',
                                v_one_email,
                                'smtp1.email.com',
                                25,
                                0,
                                Null,
                                Null,
                                v_src_location,
                                'base64');
                 End If;
              End Loop;              
              --循环发邮件结束
         End Loop;
    End;

     

    展开全文
  • 随着业务的复杂度,一般意义上的电子邮件无法满足需求,有些邮件需要附带 url附件文件。 具体公共类 MailUtils.java 如下 package com; import java.io.InputStream; import java.net.URL; import java.util....

    随着业务的复杂度,一般意义上的电子邮件无法满足需求,有些邮件需要附带 url附件文件。

    具体公共类 MailUtils.java

    如下

    package com;
    import java.io.InputStream;
    import java.net.URL;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Properties;
    
    import javax.activation.DataHandler;
    import javax.activation.DataSource;
    import javax.activation.URLDataSource;
    import javax.mail.*;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.mail.internet.MimeUtility;
    import javax.mail.util.ByteArrayDataSource;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class MailUtils {
    	
    	private String host;
    	private String port;
    	private String user;
    	private String password;
    	private String userName;
    	private String userNm_charset;
    
    	static Logger logger = LoggerFactory.getLogger(MailUtils.class);
    
    	/**
    	 * 发件,信息初始化
    	 * @param host 邮件SMTP服务器
    	 * @param port SMTP服务器端口号
    	 * @param user 发件人邮箱
    	 * @param password 发件人邮箱密码
    	 * @param userName 发件人名字
    	 */
    	public MailUtils(String host,String port, String user, String password,String userName,String userNm_charset){
    	    this.host = host;
    		this.port = port;
    	    this.user = user;
    	    this.password = password;
    		this.userName = userName;
    		this.userNm_charset = userNm_charset;
    	}
    
    	/**
    	 * 开始发件
    	 *
    	 * 说明 1,本地文件(fileName、in、inType 必须同时有值),
    	 * 	   2,网路文件(fileName、fpPdf 必须同时有值)
    	 *
    	 * @param title 邮件标题
    	 * @param toMail 收件人邮箱
    	 * @param content 邮件正文
    	 * @param fileName 附件名
    	 * @param in 附件文件流
    	 * @param inType 附件文件类型
    	 * @param fpPdf 附件url
    	 * @param ccList 抄送人邮箱
    	 * @return
    	 */
    	public boolean sendMail(String title, String toMail, String content,String fileName, InputStream in,String inType,String fpPdf,String ccList) {
    	    boolean isFlag = false;
    	    try {
    	        Properties props = new Properties();
    	        props.put("mail.smtp.host", host); // 指定SMTP服务器
    	        props.put("mail.smtp.port", port); // 指定SMTP服务器端口号
    	        props.put("mail.smtp.auth", "true"); // 指定是否需要SMTP验证
    
    			MailSSLSocketFactory sf = new MailSSLSocketFactory();
    			sf.setTrustAllHosts(true);// 设置信任所有的主机
    			props.put("mail.smtp.ssl.enable", "true");
    			props.put("mail.smtp.ssl.socketFactory", sf);
    			//props.put("mail.smtp.timeout", "25000");//超时时间
    			
    	        Session session = Session.getDefaultInstance(props);
    	        session.setDebug(false);
    	
    	        MimeMessage message = new MimeMessage(session);
    	        try {
    	            //指定发送人
    				if(userName!=null && !"".equals(userName)){
    					if(userNm_charset==null || "".equals(userNm_charset)){
    						userNm_charset = "utf-8";
    					}
    
    					message.setFrom(new InternetAddress(user,userName,userNm_charset));
    				}else{
    					message.setFrom(new InternetAddress(user));
    				}
    	            //指定接收人
    	            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail));
    	            //指定抄送人
    	            if(ccList!=null || !"".equals(ccList)){
    	                message.addRecipients(Message.RecipientType.CC,ccList);
    	            }
    	            //设置标题
    	            message.setSubject(title,"UTF-8");
    	            message.addHeader("charset", "UTF-8");
    	
    	            /*添加正文内容*/
    	            //一个Multipart对象包含一个或多个bodypart对象,组成邮件正文
    	            Multipart multipart = new MimeMultipart();
    	
    	            MimeBodyPart contentPart = new MimeBodyPart();
    	            contentPart.setText(content,"UTF-8");
    	            contentPart.setHeader("Content-Type", "text/html; charset=UTF-8");
    	            multipart.addBodyPart(contentPart);
    	
    	            /*添加附件*/
    	            if(in != null) {
    	                MimeBodyPart fileBody = new MimeBodyPart();
    	                DataSource source = new ByteArrayDataSource(in, inType);//"application/msexcel"
    	                fileBody.setDataHandler(new DataHandler(source));
    	                // 中文乱码问题
    	                fileBody.setFileName(MimeUtility.encodeText(fileName));
    	                multipart.addBodyPart(fileBody);
    	            }
    	            if(in == null && fpPdf != null) {
    	            	MimeBodyPart fileBody = new MimeBodyPart();
    	            	URL url = new URL(fpPdf);
    	                DataSource dataSource=new URLDataSource(url);
    	                DataHandler dataHandler=new DataHandler(dataSource);
    	                fileBody.setDataHandler(dataHandler);
    	                // 中文乱码问题
    	                fileBody.setFileName(MimeUtility.encodeText(fileName));
    	                multipart.addBodyPart(fileBody);
    	            }
    	
    	            message.setContent(multipart);
    	            message.setSentDate(new Date());
    	            message.saveChanges();
    	            Transport transport = session.getTransport("smtp");            
    	            transport.connect(host, user, password);
    	            transport.sendMessage(message, message.getAllRecipients());
    	            transport.close();
    	            isFlag = true;
    	            logger.info(Calendar.getInstance().getTime()+":#Send mail to"+toMail+"success #");
    	        } catch (Exception e) {
    	              logger.info(Calendar.getInstance().getTime()+":#Send mail to"+toMail+"error #");
    	            logger.info(e.toString());
    	            e.printStackTrace();
    	            isFlag = false;
    	        }
    	    } catch (Exception e) {
    	        e.printStackTrace();
    	    }
    	    return isFlag;
    	}
    }
    

    引用公共类

    如下:

    logger.info("发送邮件------>>>userEmail:{},charset:{}",userEmail,mail_userNm_charset);
                MailUtils mailUtils = new MailUtils(mail_host,mail_port,mail_user,mail_pass,mail_userNm,mail_userNm_charset);
    
                String title = "订单"+orderNo+"发票";
                //收件人
                String toMail = userEmail;
                //正文
                String content = "<h1 align=\"center\">迪信通电子发票</h1>"
                        +"<p>你好:</p>"
                        +"<p style=\"padding-left:2em;\">你申请的电子发票,详见<font style=\"font-weight:bold;color:#0000cc;font-size:20px\">附件</font>。</p>"
                        +"<p style=\"padding-left:2em;\">如未能打开,请<a target=\"_blank\" href=\""+eleInvoice.getFpUrl()+"\">点击链接</a>查看:"+eleInvoice.getFpUrl()+"</p>";
                //附件文件名
                String fileName  = "订单"+orderNo+"电子发票.pdf";
                //附件文件流
                InputStream in = null;
                //附件文件类型
                String inType = "";
                //抄送
                String ccList = "";
                mailUtils.sendMail(title, toMail, content, fileName, in,inType,eleInvoice.getFpUrl(), ccList);
    

    效果图:

    在这里插入图片描述

    展开全文
  • MailUtil.send();无法发送文件流, //这个方式只能传入本地File,无法传入网络资源 MailUtil.send();

    MailUtil.send();无法发送文件流,

    //这个方式只能传入本地File,无法传入网络资源
    MailUtil.send();

    内置Mail类实现方式

    public static void main(String[] args) throws MalformedURLException {
            MailAccount account = new MailAccount();
            account.setHost("smtp.qq.com");
            account.setPort(25);
            account.setAuth(true);
            account.setFrom("***@qq.com");
            account.setUser("***");
            account.setPass("***");
    //        使用内置Mail类添加附件内容 DataSource是一个接口,地下有很多实现来解决我们不同问题
            Mail mail = Mail.create(account);
            URLDataSource urlDataSource = new URLDataSource(new URL("http://img.netbian.com/file/2021/0611/c7c2a851020a260b348d327807414791.jpg"));
            mail.setAttachments(urlDataSource);
            mail.setTos("***@qq.com");
            mail.setTitle("标题");
            mail.setContent("内容");
            mail.setHtml(false);
            mail.send();
        }

     

    展开全文
  • ... URL to follow: ... <pre><code>if(array_key_exists('submit_check', $_POST)) { if($_POST['first_name'] !... (($_FILES["file"]["type"] == "application/doc") || ($_FILES["file"]["type"] == "application/...
  • 导致附件邮件重复发送的主要原因是客户端所在地到邮件服务器连接超时有关,如果邮件附件中的附件过大,或者客户端使用时当时宽带速度慢,邮件无法在设定的时限内发送完成。因此邮件会重复发送。一般使用...
  • 之前写过一篇博文,通过MAPI实现调用邮箱客户端发送邮件带附件,当时对ShellExecute研究不深,以为ShellExecute不能带附件,因为项目需求原因(MAPI只能调用Foxmail和Outlook邮箱客户端,无法调用网易邮箱大师),不得...
  • 这个网址http://down.chinaz.com/server/201104/340_1.htm可以下载jmail组件以及说明了安装方法。...在需要的页面引用Using jmail命名空间。 MessageClass mymessage = new MessageClass();出现无法嵌入...
  • 在网上看到有人在使用Outlook时遇到这样的情况,使用Outlook向其他非Outlook邮箱发送邮件,结果对方无法正常收到邮件附件,取而代之收到的是名字为Winmail.dat文件附件邮件。一般情况下,这是由于Outlook使用RTF...
  • 因客户要求利用系统默认发送邮件并要支持Foxmail,于是动手试了下,下面的代码可以运行,但用Foxmail发送附件很有问题:1.文件路径名不能出现空格 2.路径必须是正确否则无法打开写邮件窗体.建议用纯文本格式发送, 5.0...
  • 如果你现在用的DOMINO6以上的客户端JAR文件去与DOMINO5的服务器打交道,那么你是死活也无法让你的邮件带附件的。看了我的这篇文章会让你恍然大悟,呵呵! 其实说起开发环境的问题来了,DOMINO的新版本对旧版本的...
  • 前天,朋友跟我说,他们领导跟他反映说,发送一个带附件邮件发送不出去,这边没有退信,对方也任何回复信息。 帮他查看了一下MDaemon邮件服务器的日志。结果如下:smtp入的日志,显示成功的,但是在路由日志显示...
  •  1,邮件发送系统,吧.net从3.5升到4.0后,带附件邮件发送失败。  2,解决第一个问题后,附件的名字过长时,邮件接收方无法解析邮件名称。  原因:  1, ContentDisposition disposition = d
  • 用python发邮件(带附件)

    千次阅读 2019-09-28 17:26:06
    **未解决: **发送附件时, 不管附件的源格式是什么, 接收到的邮件中的附件文本内容都是UTF-8编码, 但是excel不支持UTF-8格式的文本. 这就导致, 附件后缀是.xls和.csv时, 预览附件会显示乱码, 也无法用...
  • 使用Python发送带附件邮件,附件名称不能使用变量进行复制, time_now=datetime.datetime.now() time_day=time_now.strftime('%Y%m%d') filename_xlsx="/data/tmp/xxxx汇总_%s.xlsx" %time_day print filename_...
  • 用Java Mail发送带有图片的html格式的邮件,针对于显示图片,一般有两种方法。1. 图片存在于服务器上,我们只需要把图片在服务器的的链接放进去即可。这种发式比较简单,但是这种方法有些缺陷:图片不支持离线浏览;...
  • 在Java邮件发送中,默认情况下,附件名称过长会自动截断且变为tcmime.*.bin,无法打开查看。 2. 乱码         编码格式问题 二、解决方案 1. 解决文件变为tcmime.*.bin &...
  • 通过反复测试得出以下观点...显示图片必须为related,如果还需要添加附件必须为multi; 图片显示方式要标明为“INLINE”(Disposition=MimeBodyPart.INLINE); 指定“Content-Type”的类型信息(Content-Type=ima...
  • 前几天自己试了下smtp命令发送邮件,当邮件附带附件时,像sohu,163,126的邮箱都能收到正常的附件,但sina邮箱收到的附件就有异常错误,无法运行和打开。 最后的解决办法是在发送附件时要换行,意思是用Base64将附件...
  • 在使用JavaMail创建邮件发送功能时,当文本内容,...功能可以实现,在pc端可以收到有内嵌静态图片的邮件,但在手机客户端图片无法显示,并以附件形式出现,解决方法是将上一条语句改写成为 Multipart multipart =
  • SmtpMail.Send("发送邮件的地址","接受邮件的地址","邮件的标题","邮件消息的内容") 这个方法很简单,不适合发送带附件邮件。 2. SmtpMail.Send(MailMessage) 此方法复杂、灵活,适合发送附件,而且可以设置...
  • Java Mail发送带有图片的html格式的邮件,针对于显示图片,一般有两种方法。1. 图片存在于服务器上,我们只需要把图片在服务器的的链接放进去即可。这种发式比较简单,但是这种方法有些缺陷:图片不支持离线浏览;...

空空如也

空空如也

1 2 3 4 5 6
收藏数 101
精华内容 40
关键字:

邮件带附件无法发送