Вам не нужно сохранять TMemoryStream
в файл, чтобы прикрепить его к электронному письму. Компонент Indy TIdMessage
гибок в типах данных, которые вы можете присоединить к нему.
Например, у Indy есть класс TIdAttachmentMemory
, который вы можете использовать, например:
uses
..., IdAttachmentMemory;
var
Attach: TIdAttachmentMemory;
begin
...
Attach := TIdAttachmentMemory.Create(IdMessage1, PDFMemoryStream); // alternatively, use PDFOleStream instead...
Attach.FileName := 'report.pdf';
// set other properties as needed...
// send the email...
...
end;
Примечание TIdAttachmentMemory
использует свой внутренний TMemoryStream
и скопирует данные источника TStream
в этот внутренний поток. Если вы хотите избежать этой копии и отправить свой TStream
как есть, вы можете получить собственный класс из TIdAttachment
для этого, например:
uses
Classes, IdAttachment, IdMessageParts, IdGlobal;
type
TIdAttachmentStream = class(TIdAttachment)
protected
FDataStream: TStream;
FDataStreamBeforeLoadPosition: TIdStreamSize;
public
constructor Create(Collection: TIdMessageParts; Stream: TStream); reintroduce;
property DataStream: TStream read FDataStream;
function OpenLoadStream: TStream; override;
procedure CloseLoadStream; override;
procedure FinishTempStream; override;
function PrepareTempStream: TStream; override;
end;
constructor TIdAttachmentStream.Create(Collection: TIdMessageParts; Stream: TStream);
begin
inherited Create(Collection);
FDataStream := Stream;
end;
procedure TIdAttachmentStream.CloseLoadStream;
begin
DataStream.Position := FDataStreamBeforeLoadPosition;
end;
function TIdAttachmentStream.OpenLoadStream: TStream;
begin
FDataStreamBeforeLoadPosition := DataStream.Position;
DataStream.Position := 0;
Result := DataStream;
end;
procedure TIdAttachmentStream.FinishTempStream;
begin
DataStream.Position := 0;
end;
function TIdAttachmentStream.PrepareTempStream: TStream;
begin
DataStream.Size := 0;
Result := DataStream;
end;
var
Attach: TIdAttachmentStream;
begin
...
Attach := TIdAttachmentStream.Create(IdMessage1, PDFMemoryStream); // alternatively, use PDFOleStream instead...
Attach.FileName := 'report.pdf';
// set other properties as needed...
// send the email...
...
end;
Или вы можете написать класс для отправки оригинала IStream
напрямую, например:
uses
Classes, IdAttachment, IdMessageParts, IdGlobal;
type
TIdAttachmentIStream = class(TIdAttachment)
protected
FDataStream: TStream;
FDataStreamBeforeLoadPosition: TIdStreamSize;
public
constructor Create(Collection: TIdMessageParts; Stream: IStream); reintroduce;
destructor Destroy; override;
property DataStream: TStream read FDataStream;
function OpenLoadStream: TStream; override;
procedure CloseLoadStream; override;
procedure FinishTempStream; override;
function PrepareTempStream: TStream; override;
end;
constructor TIdAttachmentIStream.Create(Collection: TIdMessageParts; Stream: IStream);
begin
inherited Create(Collection);
FDataStream := TOleStream.Create(Stream);
end;
destructor TIdAttachmentIStream.Destroy;
begin
FDataStream.Free;
inherited;
end;
procedure TIdAttachmentIStream.CloseLoadStream;
begin
DataStream.Position := FDataStreamBeforeLoadPosition;
end;
function TIdAttachmentIStream.OpenLoadStream: TStream;
begin
FDataStreamBeforeLoadPosition := DataStream.Position;
DataStream.Position := 0;
Result := DataStream;
end;
procedure TIdAttachmentIStream.FinishTempStream;
begin
DataStream.Position := 0;
end;
function TIdAttachmentIStream.PrepareTempStream: TStream;
begin
DataStream.Size := 0;
Result := DataStream;
end;
var
Attach: TIdAttachmentIStream;
begin
...
Attach := TIdAttachmentIStream.Create(IdMessage1, PDFReport.GetAsFile());
Attach.FileName := 'report.pdf';
// set other properties as needed...
// send the email...
...
end;