我正尝试使用 Delphi (D10 S)将PDF文档附加到电子邮件中,我想将名称设置为文件系统上文件名以外的名称。
我发现了以下线程(从2011年开始),其中雷米勒博表示,您可以通过在使用TIdMessageBuilderHtml
将TIdMessageBuilderAttachment
对象附加到电子邮件时设置TIdMessageBuilderAttachment
对象的Name
属性来实现这一点:
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中测试过了,两者都是如此。知道我哪里做错了吗
2条答案
按热度按时间rqmkfv5c1#
TIdMessageBuilderAttachment
同时具有FileName
和Name
属性。当向构建器添加附件时,这些值被分配给TIdMessage.MessageParts
集合中添加的TIdAttachment
对象的相应属性。如果附件分配了
Name
,则该值将放置在Content-Type
头的name
属性中,例如:如果附件分配了
FileName
,则该值将放置在Content-Disposition
头的filename
属性中,例如:如果两个头都存在,则符合条件的读取器在查找文件名时将给予给予
Content-Disposition
优先级。这就是为什么你的阅读器显示不需要的文件名。向构建器添加物理文件时,
TIdMessageBuilderAttachment
当前不允许您指定与真实的文件不同的FileName
。这是因为TIdMessageBuilderAttachment
并不是真正加载文件的那个。它只是创建一个新的TIdAttachmentFile
对象,并将其FileName
分配给该对象,因此它需要真实的文件名,否则发送电子邮件时附件将无法加载。但是,TIdAttachmentFile
允许在创建后自定义自己的FileName
。它有一个单独的StoredPathName
属性来跟踪物理文件,所以它的FileName
可以是任何你想要的。在@ fashion hirocco的示例中,将
TStream
添加到构建器会导致TIdAttachmentMemory
被添加到TIdMessage
,而不是TIdAttachmentFile
。由于不涉及物理文件,附件的FileName
可以是您想要的任何文件。因此,
TIdMessageBuilderAttachment
必须进行更新,以允许将物理文件附件的FileName
与其StoredPathName
分开设置。同时,您可以在填充TIdMessage
后手动更新TIdAttachmentFile.FileName
属性,例如:更新:
在这个答案第一次发布之后,这个问题已经通过在
TIdMessageBuilderAttachment
类中添加一个新的WantedFileName
属性来解决。您可以将
WantedFileName
设置为任何您想要的值,在填充TIdMessage
时,它将被分配给附件的FileName
属性。如果WantedFileName
为空,则将使用TIdMessageBuilderAttachment.FileName
属性代替,如前所述。此外,如果
TIdMessageBuilderAttachment.Name
属性也为空,则将使用WantedFileName
。因此,您现在可以在一个地方设置所需的名称,如果需要,它将用于Content-Type
和Content-Disposition
头部,例如:在填充
TIdMessage
后,不再需要手动更新TIdAttachment.FileName
属性。j0pj023g2#
使用
TIdMessageBuilderAttachments.Add
重载(它接受TStream
)并将TIdMessageBuilderAttachment.FileName
属性设置为所需的名称,这对我在 XE4,Indy 10.6.0.4975上很有用。