题
我们它的应用程序具有长期使"打印"选项,其中基本上采用RDLC.
客户已要求我们增加一个功能,让用户发送"的印刷"的输出的通过电子邮件。
现在,我们知道,一个电磁场的创建文件(在临时文件夹)作为一种隐藏的副产品,我们目前的印刷过程。
在我们看来,我们可以只需抓住这个电磁场文件,并将其连接到一个新的电子邮件和工作已经完成。
- 这是最好的选择吗?
- 我们可以依靠一个电磁场文件被打开,通过的任何Windows的机器?
- 我们如何识别的电磁场的文件?...似乎只是被命名为
%TEMP%\DiaryGrid_1.emf
目前。OK所以DiaryGrid的名字是我们的RDLC文件,但_1获取加入的地方。
解决方案
我这样做之前。我没有它的出口编程方式的报告。对一个特定的位置,那么我们的电子邮件的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;
}
现在,我们需要一类控制的邮件系统。每个邮件系统都有自己的caracteristics,所以也许你会需要修改这一类。该行为的类很简单。你只需要填补的特性,并呼吁发送的方法。在我的情况下,窗户不要让我删除的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);
}
}
现在,您可以创建一个形式要求的destinataries,添加一些验证,等等,回到你的一个实例邮件类...或者你可以简单地"硬代码"的价值和补课。
这里是代码,我在使用一个按钮调这种形式中,在我的例子是命名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是实例邮件类。我们只需要调用发送出色的工作已经完成。
这是最大的回答我曾经写了所以...我希望它能帮助你:D如果你有任何问题采用它,给我打电话。通过这种方式,我不是很自豪我的英语,所以请原谅我,如果文本有任何错误。