Jun 25, 2008

One Click Grid to Email

kick it on DotNetKicks.com

Earlier I gave the title of this blog like this 'Export Gridview Data to Excel and send it as email attachment w/o saving it on the Hard Drive'. It was too long then one of my friends (Computer Genius) suggested me this title 'One click Grid to Email'. I liked it what you think about it?

Anyways, I had assigned a work to make certain updation to the report system of one web application. Report system, of course not any third party expensive reporting tools, means exporting the data to MS Excel. You guys know that exporting the data from the Gridview control to MS Excel is not a gigantic task and i have already written a blog about it Export Dataset to Excel, so I did it with no challenge. Second task was to send the created MS Excel file as email attachment to the given email ID. I believe this is, again, not a task where you need to write mammoth code. Thanks to the Mircosoft to provide us with System.Net.Mail namespace which made our work pretty simple.

To send an email with attachment, there has always been a need that an attachment file should exist on the hard drive so that it can be attached to an outbound email. So first you export the data to Excel file, save it to the hard drive and then open the dialog box to browse the saved excel file and attach it with the email and send it whereever it is wanted.....easy job..No? (give your comments below). It is easy but annoying from user prespective, it is not user-friendly.

Instead of pressing many clicks, wish you could do it in just one click. Yes, this is what my following code is doing. In place of saving file on the hard drive, it saves the exported excel file in the memory (RAM) and attachs it to the email and sends it to sender all in just one click.

So open project, take a Gridview and a button control on the .aspx page, bind the gridview with the database and write the following code on the Button click event.

using System.Net.Mail;
using System.Text;

protected void Button1_Click(object sender, EventArgs e)
{
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
htmlWrite.WriteLine("<br />");
htmlWrite.WriteLine("<b><font size='2'>Title : Test Report</font></b>");
htmlWrite.WriteLine("<br /><br />");
GridView1.RenderControl(htmlWrite);

MemoryStream memorystream = new MemoryStream();
byte[] _bytes = Encoding.UTF8.GetBytes(stringWrite.ToString());
memorystream.Write(_bytes, 0, _bytes.Length);
memorystream.Seek(0, SeekOrigin.Begin);

MailMessage mail = new MailMessage();
mail.From = new MailAddress(ConfigurationManager.AppSettings["mailFrom"]);
mail.To.Add(new MailAddress(ConfigurationManager.AppSettings["mailTo"]));
mail.Subject = ConfigurationManager.AppSettings["mailSubject"];
mail.Body = ConfigurationManager.AppSettings["mailBody"];

mail.Attachments.Add(new Attachment(memorystream, "Report.xls" ));
SmtpClient SmtpMail = new SmtpClient(ConfigurationManager.AppSettings["smtpServer"]);
SmtpMail.Port = Int32.Parse(ConfigurationManager.AppSettings["smtpServerPort"]);
SmtpMail.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["smtpServerUsername"], ConfigurationManager.AppSettings["smtpServerPassword"]);
try
{
SmtpMail.Send(mail);
}
catch(Exception ex)
{
Response.Write("Error : " +ex);
}
finally
{
Response.Write("E-mail has been sent sucessfully");
}
}

The web.config settings are as follows:-

<appSettings>
<add key="smtpServer" value="smtp.xx.ca"/>
<add key="smtpServerPort" value="25"/>
<add key="smtpServerUsername" value="xx@rogers.ca"/>
<add key="smtpServerPassword" value="xx"/>
<add key="mailFrom" value="admin@xx.ca"/>
<add key="mailSubject" value="Report"/>
<add key="mailTo" value="xx@xx.com"/>
<add key="mailBody" value="This is a test report"/>
</appSettings>

You might get this error:

Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server.


To resolve this issue you just paste this code the same .aspx page:-

public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
}

Enjoy!!

kick it on DotNetKicks.com