Delphi 使用TIdMessageBuilderHtml设置电子邮件附件名称
我正在尝试使用Delphi(D10S)将PDF文档附加到电子邮件中,我希望将名称设置为文件系统上文件名以外的其他名称 我发现了以下线程(从2011年开始),Remy Lebeau指出,在使用Delphi 使用TIdMessageBuilderHtml设置电子邮件附件名称,delphi,smtp,indy,Delphi,Smtp,Indy,我正在尝试使用Delphi(D10S)将PDF文档附加到电子邮件中,我希望将名称设置为文件系统上文件名以外的其他名称 我发现了以下线程(从2011年开始),Remy Lebeau指出,在使用TIdMessageBuilderHtml将对象附加到电子邮件时,可以通过设置TIdMessageBuilderAttachment对象的Name属性来实现这一点: 然而,这听起来很简单,但似乎对我不起作用。电子邮件通过了,但是附件通过了原始文件名,而不是我指定的文件名 下面是一段代码,我希望按照我所描述的
TIdMessageBuilderHtml
将对象附加到电子邮件时,可以通过设置TIdMessageBuilderAttachment
对象的Name
属性来实现这一点:
然而,这听起来很简单,但似乎对我不起作用。电子邮件通过了,但是附件通过了原始文件名,而不是我指定的文件名
下面是一段代码,我希望按照我所描述的那样去做,但是,不管出于什么原因,我没有这样做。在本例中,我希望文件名显示为所需的\u filename.pdf
,但它显示为所需的\u filename.pdf
。我已删除邮件服务器凭据,原因很明显:
procedure TForm4.Button1Click(Sender: TObject);
var
FMessageBuilder : TIdMessageBuilderHtml;
FSMTP : TIdSMTP;
FMessage : TIdMessage;
FAttachment : TIdMessageBuilderAttachment;
begin
FMessage := TIdMessage.Create();
FMessageBuilder := TIdMessageBuilderHtml.Create;
FSMTP := TIdSMTP.Create;
FAttachment := FMessageBuilder.Attachments.Add('c:\undesired_filename.pdf');
FAttachment.Name := 'desired_filename.pdf';
FMessageBuilder.FillMessage(FMessage);
FMessage.Sender.Address := '<Insert Sender Address>';
FMessage.Sender.Name := '<Insert Sender Name>';
FMessage.From.Address := '<Insert From Address>';
FMessage.From.Name := '<Insert From Name>';
FMessage.Recipients.EMailAddresses := '<Insert Recepient Address>';
FMessage.Subject := 'Attachment Test';
FSMTP.Host := '<Insert Mail Host>';
FSMTP.Username := '<Insert Username>';
FSMTP.Password := '<Insert Password>';
FSMTP.Connect;
FSMTP.Send(FMessage);
FSMTP.Disconnect;
end;
程序TForm4.按钮1点击(发送者:ToObject);
变量
FMessageBuilder:TIdMessageBuilderHtml;
FSMTP:tidstp;
FMessage:TIdMessage;
FAttachment:TIdMessageBuilderAttachment;
开始
FMessage:=TIdMessage.Create();
FMessageBuilder:=TIdMessageBuilderHtml.Create;
FSMTP:=tidstp.Create;
FAttachment:=FMessageBuilder.Attachments.Add('c:\undefered_filename.pdf');
FAttachment.Name:=“所需的文件名.pdf”;
FMessageBuilder.FillMessage(FMessage);
FMessage.Sender.Address:='';
FMessage.Sender.Name:='';
FMessage.From.Address:='';
FMessage.From.Name:='';
FMessage.Recipients.EMailAddresses:='';
FMessage.Subject:=“附件测试”;
FSMTP.Host:='';
FSMTP.Username:='';
FSMTP.密码:='';
连接;
FSMTP.Send(FMessage);
断开连接;
结束;
我已经在D10和XE中测试过了,它们都做了同样的测试。知道我做错了什么吗?使用
TIdMessageBuilderAttachments.Add
重载,它接受TStream
,并将TIdMessageBuilderAttachment.FileName
属性设置为所需的名称,这对我在XE4(Indy 10.6.0.4975)上很有帮助
stream := TFileStream.Create('c:\undesired_filename.pdf', fmOpenRead);
FAttachment := FMessageBuilder.Attachments.Add(stream, 'application/pdf');
FAttachment.FileName := 'desired_filename.pdf';
TIdMessageBuilderAttachment
同时具有FileName
和Name
属性。将附件添加到生成器时,这些值将分配给添加到TIdMessage.MessageParts
集合的TIdAttachment
对象的相应属性
如果附件分配了名称
,则该值将置于内容类型
标题的名称
属性中,例如:
Content-Type: media/type; name="desired_filename.pdf"
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果附件分配了文件名
,则该值将置于内容处置
标题的文件名
属性中,例如:
Content-Type: media/type; name="desired_filename.pdf"
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果两个标题都存在,则一致性读者在查找文件名时将给予内容处置
优先级。这就是您的阅读器显示不需要的文件名的原因
将物理文件添加到生成器时,TIdMessageBuilderAttachment
当前不允许您指定与实际文件不同的文件名。这是因为TIdMessageBuilderAttachment
不是实际加载文件的。它只创建一个新的TIdAttachmentFile
对象,并将其FileName
分配给该对象,因此它需要实际的文件名,否则发送电子邮件时附件将无法加载。但是,TIdAttachmentFile
确实允许在创建后自定义自己的FileName
。它有一个单独的StoredPathName
属性来跟踪物理文件,因此它的FileName
可以是您想要的任何文件
在@Fantagirocco的示例中,将TStream
添加到生成器会导致TIdAttachmentMemory
添加到TIdMessage
中,而不是TIdAttachmentFile
。由于不涉及任何物理文件,因此附件的文件名可以是您想要的任何内容
因此,必须更新TIdMessageBuilderAttachment
,以允许将物理文件附件的文件名
与其存储路径名
分开设置。同时,您可以在填写TIdMessage
后手动更新TIdAttachmentFile.FileName
属性,例如:
FAttachment := FMessageBuilder.Attachments.Add('c:\undesired_filename.pdf');
FAttachment.Name := 'desired_filename.pdf';
FMessageBuilder.FillMessage(FMessage);
for I := 0 to FMessage.MessageParts.Count-1 do
begin
if FMessage.MessageParts[I].PartType = mptAttachment then
FMessage.MessageParts[I].FileName = FMessage.MessageParts[I].Name;
end;
那很有效,谢谢!然而,我仍然有点好奇,想知道我使用的方法有什么问题。在我把这个标记为答案之前,我会等着看是否有其他人能找到答案(我也没有足够的声誉来+1这个,但如果我能的话,我会的)。@Adam,不客气,将此视为一个解决方案,直到'ReMy将解决您的问题],这种方法的一个问题是,该重载导致输入<代码> TStase数据被复制到内存中(A<代码> TIdAttachmentMemory < /Cord>对象被添加到<代码> TIDeMase. MessageParts < /Cuff>集合),因此,这对于大型附件是不可取的。我已经将Remy的答案标记为已被接受,因为它提供了一个解决方案,并解释了为什么我的方法不起作用。我希望你不介意。@Adam根本没有问题,这是它的用途。你做得对,谢谢;)哇,我从没想到你会来回答这个问题!谢谢如果在“TIdMessageBuilderAttachment”上设置“name”属性只会更新“Content Type”标题,但“Content Disposition”(填充了我的“FileName”)具有优先权,这是否意味着您在我链接的线程中给出的示例也会有同样的问题,或者我遗漏了一些细微的差异?我只是假设他对你的答案很满意,他也会这么做。前面的例子也会遇到同样的问题。这是我第一次写它时没有考虑到的TIdMessageBuilder
的一个限制,因此我必须对它进行更新以考虑它