使用 TIdMessageBuilderHtml 设置电子邮件附件名称
Setting email attachment name using TIdMessageBuilderHtml
我正在尝试使用 Delphi (D10S) 将 PDF 文档附加到电子邮件中,我想将名称设置为文件系统上文件名称以外的名称。
我发现了以下主题(自 2011 年起),其中 Remy Lebeau 指出您可以通过在将 TIdMessageBuilderAttachment
对象附加到电子邮件时设置 Name
属性 来实现此目的使用 TIdMessageBuilderHtml
:
How to name attachment files constructed by TIdMessageBuilderHtml
然而,听起来很简单,但它似乎对我不起作用。电子邮件通过了,但附件通过了原始文件名,而不是我指定的文件名。
以下是我希望按照我所描述的那样执行的代码片段,但无论出于何种原因,它并没有。在本例中,我希望文件名显示为 desired_filename.pdf
,但显示为 undesired_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;
我已经在 D10S 和 XE 中测试过,两者都是一样的。知道我做错了什么吗?
使用接受 TStream
的 TIdMessageBuilderAttachments.Add
重载并将 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
collection.
的 TIdAttachment
object 的相应属性
如果附件分配了 Name
,值将放在 Content-Type
header 的 name
属性中,例如:
Content-Type: media/type; name="desired_filename.pdf"
如果附件分配了 FileName
,值将放在 Content-Disposition
header 的 filename
属性中,例如:
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果两个 header 都存在,则在查找文件名时符合 reader 的将给予 Content-Disposition
优先权。这就是为什么您的 reader 显示不需要的文件名。
将物理文件添加到构建器时,TIdMessageBuilderAttachment
目前不允许您指定与实际文件不同的 FileName
。这是因为 TIdMessageBuilderAttachment
不是实际加载文件的那个。它只是创建一个新的 TIdAttachmentFile
object 并将其 FileName
分配给那个 object,因此它需要真实的文件名,否则在发送电子邮件时附件将无法加载。但是,TIdAttachmentFile
允许在创建后自定义其自身的 FileName
。它有一个单独的 StoredPathName
属性 来跟踪物理文件,因此它的 FileName
可以是任何你想要的。
在@fantaghirocco 的示例中,将 TStream
添加到构建器会导致将 TIdAttachmentMemory
添加到 TIdMessage
而不是 TIdAttachmentFile
。由于不涉及物理文件,附件的 FileName
可以是您想要的任何内容。
因此,必须更新 TIdMessageBuilderAttachment
以允许将物理文件附件的 FileName
与其 StoredPathName
分开。同时,可以在TIdMessage
填满后手动更新TIdAttachmentFile.FileName
属性,eg:
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;
我正在尝试使用 Delphi (D10S) 将 PDF 文档附加到电子邮件中,我想将名称设置为文件系统上文件名称以外的名称。
我发现了以下主题(自 2011 年起),其中 Remy Lebeau 指出您可以通过在将 TIdMessageBuilderAttachment
对象附加到电子邮件时设置 Name
属性 来实现此目的使用 TIdMessageBuilderHtml
:
How to name attachment files constructed by TIdMessageBuilderHtml
然而,听起来很简单,但它似乎对我不起作用。电子邮件通过了,但附件通过了原始文件名,而不是我指定的文件名。
以下是我希望按照我所描述的那样执行的代码片段,但无论出于何种原因,它并没有。在本例中,我希望文件名显示为 desired_filename.pdf
,但显示为 undesired_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;
我已经在 D10S 和 XE 中测试过,两者都是一样的。知道我做错了什么吗?
使用接受 TStream
的 TIdMessageBuilderAttachments.Add
重载并将 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
collection.
TIdAttachment
object 的相应属性
如果附件分配了 Name
,值将放在 Content-Type
header 的 name
属性中,例如:
Content-Type: media/type; name="desired_filename.pdf"
如果附件分配了 FileName
,值将放在 Content-Disposition
header 的 filename
属性中,例如:
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果两个 header 都存在,则在查找文件名时符合 reader 的将给予 Content-Disposition
优先权。这就是为什么您的 reader 显示不需要的文件名。
将物理文件添加到构建器时,TIdMessageBuilderAttachment
目前不允许您指定与实际文件不同的 FileName
。这是因为 TIdMessageBuilderAttachment
不是实际加载文件的那个。它只是创建一个新的 TIdAttachmentFile
object 并将其 FileName
分配给那个 object,因此它需要真实的文件名,否则在发送电子邮件时附件将无法加载。但是,TIdAttachmentFile
允许在创建后自定义其自身的 FileName
。它有一个单独的 StoredPathName
属性 来跟踪物理文件,因此它的 FileName
可以是任何你想要的。
在@fantaghirocco 的示例中,将 TStream
添加到构建器会导致将 TIdAttachmentMemory
添加到 TIdMessage
而不是 TIdAttachmentFile
。由于不涉及物理文件,附件的 FileName
可以是您想要的任何内容。
因此,必须更新 TIdMessageBuilderAttachment
以允许将物理文件附件的 FileName
与其 StoredPathName
分开。同时,可以在TIdMessage
填满后手动更新TIdAttachmentFile.FileName
属性,eg:
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;