我尝试使用Delphi(D10S)将PDF文档附加到电子邮件中,并且我希望将名称设置为文件系统上文件名以外的名称。
我找到了以下帖子(2011年),其中Remy Lebeau声明您可以通过使用{{1}将Name
对象附加到电子邮件时设置TIdMessageBuilderAttachment
属性来实现此目的}:
How to name attachment files constructed by TIdMessageBuilderHtml
但是,听起来很简单,它似乎对我不起作用。电子邮件通过,但附件是原始文件名,而不是我指定的文件名。
以下是我希望按照我所描述的方式执行的代码片段,但无论出于何种原因,它都没有。在这种情况下,我希望文件名为TIdMessageBuilderHtml
,但它会以desired_filename.pdf
的形式出现。我出于显而易见的原因删除了邮件服务器凭据:
undesired_filename.pdf
我在D10S和XE中对此进行了测试,两者都做了同样的事情。我有什么想法我做错了吗?
答案 0 :(得分:5)
使用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';
答案 1 :(得分:3)
TIdMessageBuilderAttachment
同时拥有FileName
和Name
属性。向构建器添加附件时,会将这些值分配给TIdAttachment
对象的相应属性,这些属性将添加到TIdMessage.MessageParts
集合中。
如果附件分配了Name
,则该值会放在name
标题的Content-Type
属性中,例如:
Content-Type: media/type; name="desired_filename.pdf"
如果附件分配了FileName
,则该值会放在filename
标题的Content-Disposition
属性中,例如:
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果两个标题都存在,符合标准的读者在查找文件名时将优先Content-Disposition
。这就是为什么您的读者显示不需要的文件名。
向构建器添加物理文件时,TIdMessageBuilderAttachment
当前不允许您指定与真实文件不同的FileName
。这是因为TIdMessageBuilderAttachment
不是实际加载文件的那个。它只是创建一个新的TIdAttachmentFile
对象并将其FileName
分配给该对象,因此它需要真实的文件名,否则在发送电子邮件时附件将无法加载。但是,TIdAttachmentFile
确实允许在创建后自定义FileName
。它有一个单独的StoredPathName
属性来跟踪物理文件,因此它的FileName
可以是您想要的任何内容。
在@ fantaghirocco的示例中,向构建器添加TStream
会导致TIdAttachmentMemory
添加到TIdMessage
而不是TIdAttachmentFile
。由于不涉及物理文件,因此附件的FileName
可以是您想要的任何内容。
因此,必须更新TIdMessageBuilderAttachment
以允许将物理文件附件FileName
与其StoredPathName
分开设置。在此期间,您可以在TIdAttachmentFile.FileName
填写后手动更新TIdMessage
属性,例如:
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;