質問

WinFormsアプリケーションでは、基本的にRDLCを使用する「印刷」オプションが長い間許可されています。

顧客は、ユーザーが電子メールで「印刷された」出力を送信できる機能を追加することを要求しました。

これで、現在の印刷プロセスの一種の隠された副産物として(TEMPフォルダー内で)EMFファイルが作成されていることがわかります。

私たちには、このEMFファイルを簡単につかんで新しい電子メールに添付できるようになり、ジョブが完了するようになります。

  1. これは最良の選択肢ですか?
  2. WindowsマシンによってEMFファイルを開くことはできますか?
  3. EMFファイルをどのように識別しますか? ...名前が付けられているようです %TEMP%\DiaryGrid_1.emf 現在。わかりましたので、日記はRDLCファイルの名前ですが、_1は途中でどこかに追加されます。
役に立ちましたか?

解決

私は前にそれをしました。レポートをPDFにプログラムで特定の場所にエクスポートし、PDFファイルを電子メールで送信して削除しました。私はあなたのためのコードを見つけようとします(今は家にいません)

編集:

後で申し訳ありません。今、私は家にいます。私はあなたにあなたのタスクを非表示にするための助けを与えると思ういくつかのコードブロックをあなたに与えます。私のプロジェクトで具体的なことを理解できるように、コードにいくつかのコメントを含めます。このコードはテストされており、クライアントではうまく機能していますが、改善できると確信しています。このコードを改善できるかどうか教えてください;)

まず、レポートを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;
}

これで、メールシステムを制御するクラスが必要です。すべてのメールシステムには独自のカラタリスティックがあるため、このクラスを変更する必要があるかもしれません。クラスの動作は簡単です。プロパティを埋めて、送信メソッドを呼び出すだけです。私の場合、Windowsは送信したらPDFファイルを削除させません(Windowsにはファイルが使用されていると書かれています)ので、次の再起動で削除されるようにファイルをプログラムします。削除メソッドをご覧ください。 SendメソッドはMailConfigという名前のCutomクラスを使用していることに注意してください。これは、ホスト、ユーザー名、パスワードなどの構成文字列を備えた小さなクラスです。メールは、このパラメーションを使用して送信されます。

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);
   }
}

これで、運命を要求するフォームを作成したり、検証などを追加したり、メールクラスのインスタンスを返すこともできます。または、単に値を「ハードコード」してクラスを埋めることができます。

このフォームを呼び出すためにボタンで使用するコードは次のとおりです。私の例では、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はメールクラスのインスタンスです。 Methisを送信するだけで、作業が行われます。

これは私がこれまでに書いた最大の答えです...それがあなたを助けることを願っています:Dあなたがそれを使用して問題があるならば、私に電話してください。ちなみに、私は私の英語をあまり誇りに思っていないので、テキストに間違いがあるならば、私を許してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top