【问题标题】:Distributing RDLC output as an email attachment将 RDLC 输出作为电子邮件附件分发
【发布时间】:2011-04-20 10:35:15
【问题描述】:

我们的 winforms 应用程序长期以来一直允许基本上使用 RDLC 的“打印”选项。

客户要求我们添加一项功能,允许用户通过电子邮件发送“打印”输出。

现在,我们知道创建了一个 EMF 文件(在 TEMP 文件夹中)作为我们当前打印过程的一种隐藏副产品。

在我们看来,我们可以简单地获取此 EMF 文件并将其附加到新电子邮件中,然后工作就完成了。

  1. 这是最好的选择吗?
  2. 我们可以依赖任何 Windows 机器打开的 EMF 文件吗?
  3. 我们如何识别 EMF 文件? ...目前似乎被命名为 %TEMP%\DiaryGrid_1.emf。好的,所以 DiaryGrid 是我们的 RDLC 文件的名称,但 _1 会被添加到某个地方。

【问题讨论】:

    标签: winforms rdlc .emf


    【解决方案1】:

    我以前做过。我以编程方式将报告导出为 pdf 到特定位置,然后我们通过电子邮件发送 pdf 文件并将其删除。我会尝试为您找到代码(现在不在家里)

    已编辑:

    对不起,稍后。现在我在家,我会给你一些代码块,我认为它们会给你一些帮助来完成你的任务。我将在代码中包含一些 cmets,以便您了解我的项目中特定的一些内容。这段代码已经过测试并且在我的客户中运行良好,但我确信它可以改进。请让我知道您是否可以改进此代码;)

    首先,我们将报告导出为pdf。

    private string ExportReportToPDF(string reportName)
    {
       Warning[] warnings;
       string[] streamids;
       string mimeType;
       string encoding;
       string filenameExtension;
       byte[] bytes = ReportViewer1.LocalReport.Render(
          "PDF", null, out mimeType, out encoding, out filenameExtension,
           out streamids, out warnings);
    
       string filename = Path.Combine(Path.GetTempPath(), reportName);
       using (var fs = new FileStream(filename, FileMode.Create))
       {
          fs.Write(bytes, 0, bytes.Length);
          fs.Close();
       }
    
       return filename;
    }
    

    现在,我们需要一个控制邮件系统的类。每个邮件系统都有自己的特点,所以也许你需要修改这个类。类的行为很简单。您只需要填写属性,然后调用 Send 方法。就我而言,Windows 不允许我在发送 pdf 文件后将其删除(Windows 表示该文件正在使用中),因此我将文件编程为在下次重新启动时删除。看一下删除方法。请注意,发送方法使用一个名为 MailConfig 的自定义类。这是一个小类,有一些配置字符串,如主机、用户名和密码。邮件将使用此参数发送。

    public class Mail
    {
       public string Title { get; set; }
       public string Text { get; set; }
       public string From { get; set; }
       public bool RequireAutentication { get; set; }
       public bool DeleteFilesAfterSend { get; set; }
    
       public List<string> To { get; set; }
       public List<string> Cc { get; set; }
       public List<string> Bcc { get; set; }
       public List<string> AttachmentFiles { get; set; }
    
       #region appi declarations
    
       internal enum MoveFileFlags
       {
          MOVEFILE_REPLACE_EXISTING = 1,
          MOVEFILE_COPY_ALLOWED = 2,
          MOVEFILE_DELAY_UNTIL_REBOOT = 4,
          MOVEFILE_WRITE_THROUGH = 8
       }
    
       [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
       static extern bool MoveFileEx(string lpExistingFileName,
                                     string lpNewFileName,
                                     MoveFileFlags dwFlags);
    
       #endregion
    
       public Mail()
       {
          To = new List<string>();
          Cc = new List<string>();
          Bcc = new List<string>();
          AttachmentFiles = new List<string>();
          From = MailConfig.Username;
       }
    
       public void Send()
       {
          var client = new SmtpClient
          {
             Host = MailConfig.Host,
             EnableSsl = false,
          };
    
          if (RequireAutentication)
          {
             var credentials = new NetworkCredential(MailConfig.Username, 
                                                     MailConfig.Password);
             client.Credentials = credentials;
          }
    
          var message = new MailMessage
          {
             Sender = new MailAddress(From, From),
             From = new MailAddress(From, From)
          };
    
          AddDestinataryToList(To, message.To);
          AddDestinataryToList(Cc, message.CC);
          AddDestinataryToList(Bcc, message.Bcc);
    
          message.Subject = Title;
          message.Body = Text;
          message.IsBodyHtml = false;
          message.Priority = MailPriority.High;
    
          var attachments = AttachmentFiles.Select(file => new Attachment(file));
          foreach (var attachment in attachments)
             message.Attachments.Add(attachment);
    
          client.Send(message);
    
          if (DeleteFilesAfterSend)
             AttachmentFiles.ForEach(DeleteFile);
       }
    
       private void AddDestinataryToList(IEnumerable<string> from,
          ICollection<MailAddress> mailAddressCollection)
       {
          foreach (var destinatary in from)
             mailAddressCollection.Add(new MailAddress(destinatary, destinatary));
       }
    
       private void DeleteFile(string filepath)
       {
          // this should delete the file in the next reboot, not now.
          MoveFileEx(filepath, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
       }
    }
    

    现在,您可以创建一个表单来询问目的地,添加一些验证等,向您返回 Mail 类的实例......或者您可以简单地“硬编码”值并填充类。

    这是我在按钮中调用此表单的代码,在我的示例中它被命名为 SendMailView。

    private void BtnSendByMail_Click(object sender, EventArgs e)
    {
       SendMailView sendMailView = new SendMailView();
    
       if (sendMailView.ShowDialog()== DialogResult.OK)
       {
          Mail mail = sendMailView.CurrentItem;
          mail.AttachmentFiles.Add(ExportReportToPDF("Invoice.pdf"));
          mail.DeleteFilesAfterSend = true;
          mail.RequireAutentication = true;
          mail.Send();
       }
       sendMailView.Dispose();
    }
    

    在本例中,senMailView.CurrentItem 是邮件类的实例。我们只需要调用 Send 方法就可以了。

    这是我写过的最大答案...希望对您有所帮助 :D 如果您在使用它时有任何问题,请给我打电话。顺便说一句,我对我的英语不是很自豪,如果文字有任何错误,请见谅。

    【讨论】:

    • 祝你好运:D 如果您有任何问题或疑问,请告诉我。
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2015-09-09
    • 2013-02-26
    相关资源
    最近更新 更多