Я сделал это раньше. Я сделал это, программно экспортировав отчет в 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;
}
Теперь нам нужен класс, управляющий почтовой системой. Каждая почтовая система имеет свои характеристики, поэтому, возможно, вам потребуется изменить этот класс. Поведение класса простое. Вам нужно только заполнить свойства и вызвать метод Send. В моем случае Windows не позволяет мне удалить файл PDF после его отправки (Windows сообщает, что файл используется), поэтому я программирую удаление файла при следующей перезагрузке. Обратите внимание на метод удаления. Обратите внимание, что метод отправки использует класс cutom с именем 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 methis, и работа сделана.
Это самый большой ответ, который я когда-либо писал в SO ... Надеюсь, он вам поможет: D Если у вас возникнут проблемы с его использованием, позвоните мне. Кстати, я не очень горжусь своим английским, так что простите меня, если в тексте есть ошибки.
person
Jonathan
schedule
03.10.2010