Question

Notre application WinForms a longtemps permis une option "d'impression" qui utilise essentiellement RDLC.

Le client a demandé que l'on ajoute une fonctionnalité permettant aux utilisateurs d'envoyer la sortie « imprimée » par courrier électronique.

Maintenant, nous savons qu'un fichier EMF est créé (dans le dossier TEMP) comme une sorte de sous-produit caché de notre processus d'impression en cours.

Semble nous, nous pouvons simplement récupérer ce fichier EMF et l'attacher à un nouvel e-mail et le travail est fait.

  1. Est-ce la meilleure option?
  2. Peut-on compter sur un fichier EMF être ouvert par une machine Windows?
  3. Comment nous identifions le fichier EMF? ... semble juste être nommé %TEMP%\DiaryGrid_1.emf actuellement. OK si DiaryGrid est le nom de notre fichier RDLC mais le _1 obtient quelque part ajouté le long du chemin.
Était-ce utile?

La solution

Je l'ai fait auparavant. Je l'ai fait exporter le rapport programatically un pdf à un endroit précis, nous envoyer le fichier pdf et le supprimer. Je vais essayer de trouver le code pour vous (pas dans la maison maintenant)

ÉDITÉ:

Désolé pour le plus tard. Maintenant, je suis à la maison et je vais vous donner quelques blocs de code que je pense vous donner un peu d'aide à acomplish votre tâche. Je vais inclure quelques commentaires au code afin que vous puissiez comprendre certaines choses qui sont spécifiques dans mon projet. Ce code sont testés et fonctionnent bien dans mes clients, mais je suis sûr qu'il peut être amélioré. S'il vous plaît, laissez-moi savoir si vous pouvez améliorer ce code;)

Tout d'abord, nous allons exporter le rapport au format 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;
}

Maintenant, nous avons besoin d'une classe qui contrôle le système de messagerie. Chaque système de messagerie a ses propres caractéristiques, il vous faut alors peut-être modifier cette classe. Le comportement de la classe est simple. Il vous suffit de remplir les propriétés et appeler la méthode Send. Dans mon cas, les fenêtres ne me laissez pas supprimer le fichier pdf une fois que je l'envoie (Windows dit que le fichier est utilisé), donc je programme le fichier à supprimer dans le prochain redémarrage. Jetez un oeil à la méthode de suppression. S'il vous plaît, notez que la méthode d'envoi utilise une classe nommée cutom mailconfig. Ceci est une petite classe qui a des chaînes de configuration comme hôte, le nom d'utilisateur et mot de passe. Le mail sera envoyé à l'aide params.

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

Maintenant, vous pouvez créer un formulaire pour demander les destinataries, ajouter un peu de validation, etc, retour à vous une instance de la classe Mail ... ou vous pouvez simplement « coder en dur » les valeurs et remplir la classe.

Voici le code que j'utilise dans un bouton pour appeler cette forme, dans mon exemple, il est nommé 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();
}

Dans cet exemple senMailView.CurrentItem est l'instance de la classe de courrier. Nous avons simplement besoin de faire appel aux Envoyer Methis et le travail est fait.

est la plus grande réponse que j'ai jamais écrit dans SO ... Je l'espère vous aider à: D Si vous avez un problème à l'utiliser, appelez-moi. Soit dit en passant, je ne suis pas très fier de mon anglais, alors pardonnez-moi si le texte a une erreur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top