设为首页 加入收藏

TOP

技术笔记:Indy控件发送邮件(一)
2017-10-10 12:07:21 】 浏览:8308
Tags:技术 笔记 Indy 控件 发送 邮件

工作中有个需求需要发送邮件,因为使用的delphi6,所以自然就选择了indy组件,想想这事挺简单的。实现的过程倒是简单,看着Indy的demo很快就完了,毕竟也不是很复杂的功能。

 

功能要求:

1、压缩日志文件并作为邮件的附件

2、邮件正文带上一些客户端信息

 

组件介绍

TIdSmtp:与服务器的连接及数据发送,基于smtp协议

TIdMessage:自然就是报文的信息了,包含收件人、发件人、主题、正文,以及附件。

 

代码展示:

function TfrmMailSend.SendMail: Boolean;
var
  objMailBody: TStrings;
begin
  Result := False;
  IdSMTP1.Username := FMailSetting.Username;
  IdSMTP1.Password := FMailSetting.Password;
  IdSMTP1.Host := FMailSetting.Host;
  IdSMTP1.Port := FMailSetting.Port;
  IdSMTP1.AuthenticationType := atLogin;

  IdMessage1.Priority := mpNormal;
  IdMessage1.From.Text := FMailSetting.FromAddress;
  IdMessage1.Recipients.EMailAddresses := edtToAddress.Text;

  IdMessage1.Subject := '日志:'+FormatDateTime('YYYY-MM-DD', dtpLogDate.Date) + '['+hsGetOperatorNo+']';
  objMailBody := TStringList.Create;
  try
    objMailBody.Add('<table>');
    objMailBody.Add('<tr><td><b>ClientID:</b></td><td>'+ hsGetClientID + '</td></tr>');
    objMailBody.Add('<tr><td><b>CompanyName:</b></td><td>'+ AnsiToUtf8('中文革') + '</td></tr>');
    objMailBody.Add('<tr><td><b>Server DateTime:</b></td><td>'+ DateTimeToStr(GetServerDateTime) + '</td></tr>');
    objMailBody.Add('</table>');
    
    //可能是Indy的bug,需要创建两次TIdText才能成功发送内容
    with TIdText.Create(IdMessage1.MessageParts, objMailBody) do
    begin
      ContentType:='text/html;charset=utf-8';
      ContentTransfer := 'quoted-printable'; //不能用base64,indy控件没实现
    end;
    with TIdText.Create(IdMessage1.MessageParts, objMailBody) do
    begin
      ContentType := 'text/html;charset=utf-8';
      ContentTransfer := 'quoted-printable'; //不能用base64,indy控件没实现
    end;
  finally
    FreeAndNil(objMailBody);
  end;


  try
    IdSMTP1.Connect;
    try
      IdSMTP1.Send(IdMessage1);
      Result := True;
    finally
      if IdSMTP1.Connected then
        IdSMTP1.Disconnect;
    end;
  except
      on e: Exception do
        Console('[发送异常]'+e.Message);
  end;
end;

代码流程主要是先准备好smtp主机信息,用户名与密码。然后组织好邮件内容,然后连接并发送。

关于附件

附件添加比较简单,Indy封装了一个专门的消息类TIdAttachment,只要将文件用TIdAttachment附加即可:

TIdAttachment.Create(IdMessage1.MessageParts, AFileName);

这样就可以将附件添加到邮件人内容中了。

 

解决中文乱码问题

写这个小程序最头痛的就是中文乱码问题,由于对这个组件不熟悉,找了半天也没找到办法解决。因为delphi早期版本一直都是基于ansi字符集,所以对于中文需要支持时就得专门处理。对email的协议也不太熟悉,只知道是编码问题,但找了老半天也没找到相着的解决方法。设置了IdMessage的CharSet也没有效果。

于是没办法就只要查看foxmail,QQ邮箱之类的邮件原文来看看差别。发现主要是三个点:

Content-Type: text/html;
charset="GB2312"
Content-Transfer-Encoding: quoted-printable

对于前两个好理解,和html协议类似。但Content-Transfer-Encoding没怎么接触过。

Content-Transfer-Encoding主要值:

7bit:用于不编码的数据。数据为 7 位 US-ASCII 字符,总行长不超过 1000 个字符。

base64:不用解释了。这个通常用于字节流,比较附件就用这个格式。

quoted-printable:将由 US-ASCII 字符集中可打印的字符组成的数据编码。

之所以是中文乱码,原因是添加邮件正文时的字符集与接收邮件客户端的字符集对上。比如Delphi默认发送的时候文本是Ansi的,结果Foxmail却是不支持。只有GB2312、UTF-8之类的。查看邮件正文:

Content-Type: text/html;
charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

这样一来肯定就显示乱码了,因为发的时候他中文并不是UTF-8的格式。解决这个问题办法也简单,那就把字符串转正特定的编码再发吧。

还好delphi里有个函数直接就用:

AnsiToUtf8('中文革')

这样发过去的内容中文就可以显示了。

发送Html

直接在TIdMessage的body内容发送其实是text/plain,这种明格式的话就不太

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Firemonkey TComboBox 下拉菜单字.. 下一篇Firemonkey 在 iOS 平台能显示更..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目