Delphi Indy 10 pdf附件不可读

35g0bw71  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(130)

我试图将报告导出为PDF格式,然后将其附加到电子邮件和/或彩信中。我用base64将TFileStream编码为TStringStream,然后将其附加到电子邮件中,但是cannot open it.使用相同的TStringStream,我将其附加到MMS中,它可以按预期工作。Indy方法似乎可以在流中工作,我做错了什么?
编辑:电子邮件附件和电子邮件正文出现在附件中,这就是为什么它不可读的原因。如果我用base64对附件的内容进行解码,它就能工作。
知道为什么会这样吗
Email Attachment
MMS Attachment

ReportPdf := TStringStream.Create;
try
  if (CreateReportPdf(QuickRep1, ReportPdf, QryInfoPrintNumber.AsString, 'REPORT', IsReprint)) then
  begin
    if (Assigned(ReportPdf)) then
    begin
      SendReceiptEmail(ReportPdf, QryInfoPrintNumber.AsString, 'REPORT', QryReportName.AsString, 'Test', QryInfoReplyToEmailAddress.AsString);
      SendReceiptSMS(ReportPdf, QryInfoPrintNumber.AsString, 'REPORT', QryReportName.AsString, 'Test');
    end;
  end;
finally
  ReportPdf.Free;
end;

字符串
这里是报告导出的位置。这和预期的一样。

function CreateReportPdf(QuickRep: TQuickRep; var ReportPdf: TStringStream; const PrintNumber, ReportName: string; const IsReprint: Boolean): Boolean;
var
  aPdf: TQRPDFDocumentFilter;
  tmpPath, tmpFileName: string;
  fs: TFileStream;
begin
  Result := False;
  if (not Assigned(QuickRep)) then
    Exit;

  tmpPath := GetSpecialFolderPath(CSIDL_LOCAL_APPDATA) + '\Temp\';
  tmpFileName := CreateTmpFileName(tmpPath, Format('%s_%s', [ReportName, PrintNumber]), '.pdf');

  aPdf := TQRPDFDocumentFilter.Create(tmpPath + tmpFileName);
  fs := nil;

  try
    try
      aPdf.CompressionOn := True;
      aPdf.PageLength := 11;
      QuickRep.ExportToFilter(aPdf);

      fs := TFileStream.Create(tmpPath + tmpFileName, fmOpenRead);
      fs.Position := 0;
      TNetEncoding.Base64.Encode(fs, ReportPdf);

      Result := True;
    except
      ShowMessage('Failed to create report PDF.');
      Result := False;
    end;
  finally
    aPdf.Free;
    fs.Free;
  end;
end;


我试过解码base64(见下文)--没有帮助。

procedure SendReportEmail(ReportPdf: TStringStream; const PrintNumber, ReportName, Recipients, MessageText, ReplyTo: string);
var
  Attachment: TStringList;
  Host: string;
  Port: Integer;
  // ReportPdfDecoded: TStringStream;
  I: Integer;
begin
  if (ReportPdf.DataString.Length > 0) then
  begin
    ReportPdf.Position := 0;   
    // ReportPdfDecoded := TStringStream.Create;
    Attachment := TStringList.Create();

    try
      // TNetEncoding.Base64.Decode(ReportPdf, ReportPdfDecoded);
      // Attachment.AddObject('stream/pdf', ReportPdfDecoded);
      Attachment.AddObject('stream/pdf', ReportPdf);          

      Host := GetConfigValue(cCFG_EMAIL_HOST).AsString;
      Port := GetConfigValue(cCFG_EMAIL_PORT).AsInteger;
      From := GetConfigValue(cCFG_EMAIL_FROM).AsString;

      Lib.SendEmail(Host, From, Recipients, ReportName + '_' + PrintNumber,
        MessageText, '', '', ReplyTo, Port, False, Attachment);
    finally
      for I := Attachment.Count -1 downto 0 do
        Attachment.Objects[I].Free;
      Attachment.Free;
      // ReportPdfDecoded.Free;
    end;
  end;
end;


我错过了什么明显的东西吗?谢谢你帮我找

procedure SendEmail(Host, From, Recipients, Subject, Body, CC, BCC, ReplyTo: string; Port: Integer; IsBodyHtml: Boolean; Attachments: TStrings);
var
  IdSMTP: TIdSMTP;
  IdMessage: TIdMessage;
  builder: TIdCustomMessageBuilder;
  s: Integer;
begin
  IdSMTP := TIdSMTP.Create(nil);
  IdMessage := TIdMessage.Create(nil);

  try
    if IsBodyHtml then
    begin
      builder := TIdMessageBuilderHtml.Create;
      TIdMessageBuilderHtml(builder).Html.Text := Body
    end
    else
    begin
      builder := TIdMessageBuilderPlain.Create;
    end;

    try
      if (Assigned(Attachments)) then
      begin
        IdMessage.ContentType := 'multipart/mixed';
        for s := 0 to Attachments.Count -1 do
        begin
          if (Attachments.Strings[s] = 'stream/pdf') then
          begin
            builder.PlainTextCharSet := 'utf-8';
            builder.Attachments.Add(TStringStream(attachments.Objects[s]), 'application/pdf');
          end
          else
            builder.Attachments.Add(attachments.ValueFromIndex[s]);
        end;
      end;

      builder.FillMessage(IdMessage);
    finally
      builder.Free;
    end;

    IdMessage.From.Address := From;
    IdMessage.Recipients.EMailAddresses := Recipients;
    IdMessage.Subject := Subject;
    IdMessage.Body.Text := Body;
    IdMessage.CCList.EMailAddresses := CC;
    IdMessage.BccList.EMailAddresses := BCC;
    IdMessage.ReplyTo.EMailAddresses := ReplyTo;

    if not IsBodyHtml then
      IdMessage.Body.Text := Body;
      
    try
      IdSMTP.Host := Host;
      IdSMTP.Port := Port;

      IdSMTP.Connect;
      IdSMTP.Send(IdMessage);
      IdSMTP.Disconnect;
    finally
      IdSMTP.Free;
    end;
  finally
    IdMessage.Free;
  end;
end;

wecizke3

wecizke31#

没有必要 * 手动 * base64-编码PDF之前与Indy电子邮件(如果你需要base64的短信,你应该单独处理,在你发送短信的点)。Indy的TIdMessage组件可以为您处理base64,所以只需按原样附加原始PDF并将其ContentTransfer属性设置为'base64'即可。由于您将PDF存储到TStream中,然后将其附加到电子邮件中,因此您应该仅存储PDF的原始字节(即,使用TMemoryStreamTFileStream),不要存储PDF的预编码版本。
试试类似这样的东西:

ReportPdf := TMemoryStream.Create;
try
  if CreateReportPdf(QuickRep1, ReportPdf, QryInfoPrintNumber.AsString, 'REPORT', IsReprint) then
  begin
    SendReceiptEmail(ReportPdf, QryInfoPrintNumber.AsString, 'REPORT', QryReportName.AsString, 'Test', QryInfoReplyToEmailAddress.AsString);
    ...
  end;
finally
  ReportPdf.Free;
end;

x

function CreateReportPdf(QuickRep: TQuickRep; ReportPdf: TMemoryStream; const PrintNumber, ReportName: string; const IsReprint: Boolean): Boolean;
var
  aPdf: TQRPDFDocumentFilter;
  tmpPath, tmpFileName: string;
begin
  Result := False;
  if not Assigned(QuickRep) then
    Exit;
    
  tmpPath := GetSpecialFolderPath(CSIDL_LOCAL_APPDATA) + '\Temp\';
  tmpFileName := CreateTmpFileName(tmpPath, Format('%s_%s', [ReportName, PrintNumber]), '.pdf');
    
  try
    aPdf := TQRPDFDocumentFilter.Create(tmpPath + tmpFileName);    
    try
      aPdf.CompressionOn := True;
      aPdf.PageLength := 11;
      QuickRep.ExportToFilter(aPdf);
    
      ReportPdf.LoadFromFile(tmpPath + tmpFileName);
      Result := True;
    finally
      aPdf.Free;
    end;
  except
    ShowMessage('Failed to create report PDF.');
  end;
end;
procedure SendReportEmail(ReportPdf: TMemoryStream; const PrintNumber, ReportName, Recipients, MessageText, ReplyTo: string);
var
  Attachment: TStringList;
  Host, From: string;
  Port: Integer;
begin
  if ReportPdf.Size > 0 then
  begin
    ReportPdf.Position := 0;   

    Attachment := TStringList.Create;    
    try
      Attachment.AddObject('stream/pdf', ReportPdf);          
    
      Host := GetConfigValue(cCFG_EMAIL_HOST).AsString;
      Port := GetConfigValue(cCFG_EMAIL_PORT).AsInteger;
      From := GetConfigValue(cCFG_EMAIL_FROM).AsString;
    
      Lib.SendEmail(Host, From, Recipients, ReportName + '_' + PrintNumber,
        MessageText, '', '', ReplyTo, Port, False, Attachment);
    finally
      Attachment.Free;
    end;
  end;
end;
procedure SendEmail(Host, From, Recipients, Subject, Body, CC, BCC, ReplyTo: string; Port: Integer; IsBodyHtml: Boolean; Attachments: TStrings);
var
  IdSMTP: TIdSMTP;
  IdMessage: TIdMessage;
  builder: TIdMessageBuilderHtml;
  attach: TIdMessageBuilderAttachment;
  I: Integer;
begin
  IdMessage := TIdMessage.Create(nil);  
  try
    builder := TIdMessageBuilderHtml.Create;
    try
      builder.PlainTextCharSet := 'utf-8';
      builder.HtmlCharSet := 'utf-8';

      if IsBodyHtml then
        builder.Html.Text := Body
      else
        builder.PlainText.Text := Body;
    
      if Assigned(Attachments) then
      begin
        for I := 0 to Attachments.Count - 1 do
        begin
          if Attachments.Strings[I] = 'stream/pdf' then
          begin
            attach := builder.Attachments.Add(TMemoryStream(attachments.Objects[I]), 'application/pdf');
            attach.ContentTransfer := 'base64';
          else
            attach := builder.Attachments.Add(attachments.ValueFromIndex[I]);

          // optional: set attach.WantedFileName or attach.FileName if desired...
        end;
      end;
    
      builder.FillMessage(IdMessage);
    finally
      builder.Free;
    end;
    
    IdMessage.From.Address := From;
    IdMessage.Recipients.EMailAddresses := Recipients;
    IdMessage.Subject := Subject;
    IdMessage.CCList.EMailAddresses := CC;
    IdMessage.BccList.EMailAddresses := BCC;
    IdMessage.ReplyTo.EMailAddresses := ReplyTo;

    IdSMTP := TIdSMTP.Create(nil);
    try
      IdSMTP.Host := Host;
      IdSMTP.Port := Port;
    
      IdSMTP.Connect;
      try
        IdSMTP.Send(IdMessage);
      finally
        IdSMTP.Disconnect;
      end;
    finally
      IdSMTP.Free;
    end;
  finally
    IdMessage.Free;
  end;
end;

的数据

相关问题