Introduction
The article "ASP.Net 2.0: Export GridView to Excel" received a very good response from our user community. Some of the excellent tips collected from the user feedback have been included in the first version of the article.
One of the most common questions from our readers is regarding the handling of a Hyperlink column in the GridView Export to Excel. This article will expand on the original article and in this version, we will include the handling the export of the Hyperlink columns in the GridView export to Excel functionality and also re-factor our original logic to use more general features of reflection, allowing for easy extension to include additional control types. This code generalization does have a performance overhead and if the controls embedded in your GridView are limited to a particular set, the original implementation may be more suitable for your requirements.
Architectural Changes
- Define a Hash Table which holds the values for the controls to be replaced before the GridView control is exported to Excel.
This HashTable will map the control types that can be potentially embedded in the GridView to the corresponding control property that will be used to represent the particular control when exported to Excel.
- The generalized "GetControlPropertyValue" method: In this version, we define a generalized method which will fetch the value of "key" property of the embedded control by using Reflection. We define the key properties for different types of embedded control using our HashTable member variable.
Our HashTable has been setup to perform the following property mappings.
Control Type Corresponding Value to Represent in Excel LinkButton or derived class Text Property value HyperLink or derived class Text Property value DropDownList or derived class SelectedValue Property Value CheckBox or derived class Checked Property Value
If you need to handle additional control types separately for the export process, these control types can be added to the Hashtable.
- New version of the PrepareGridViewForExport method: In this updated version, we get the "key" property for the control types that we have defined for replacement in our gridview, by calling GetControlPropertyValue if the control type or it's base type is included in the Hashtable for special handling. The control embedded in the GridView is then replaced by the value of the key property. After all the controls embedded in the GridView are processed recursively, the GridView is rendered into an HtmlTextWriter and output to the Excel formatted response.
Complete Code Listing
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
using System.Reflection;
public partial class DeleteConfirm : System.Web.UI.Page
{
Hashtable htControls = new Hashtable();
protected void Page_Load(object sender, EventArgs e)
{
htControls.Add("LinkButton", "Text");
htControls.Add("HyperLink", "Text");
htControls.Add("DropDownList", "SelectedItem");
htControls.Add("CheckBox", "Checked");
}
protected void Button1_Click(object sender, EventArgs e)
{
PrepareGridViewForExport(GridView1);
ExportGridView();
}
private void ExportGridView()
{
string attachment = "attachment; filename=Contacts.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/ms-excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
GridView1.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
public override void VerifyRenderingInServerForm(Control control)
{
}
private void PrepareGridViewForExport(Control gv)
{
Literal l = new Literal();
for (int i = 0; i < gv.Controls.Count; i++)
{
if ((null != htControls[gv.Controls[i].GetType().Name]) || (null != htControls[gv.Controls[i].GetType
().BaseType.Name]))
{
l.Text = GetControlPropertyValue(gv.Controls[i]);
gv.Controls.Remove(gv.Controls[i]);
gv.Controls.AddAt(i, l);
}
if (gv.Controls[i].HasControls())
{
PrepareGridViewForExport(gv.Controls[i]);
}
}
}
private string GetControlPropertyValue(Control control)
{
Type controlType = control.GetType();
string strControlType = controlType.Name;
string strReturn = "Error";
bool bReturn;
PropertyInfo[] ctrlProps = controlType.GetProperties();
string ExcelPropertyName = (string)htControls[strControlType];
if (ExcelPropertyName == null)
{
ExcelPropertyName = (string)htControls[control.GetType().BaseType.Name];
if (ExcelPropertyName == null)
return strReturn;
}
foreach (PropertyInfo ctrlProp in ctrlProps)
{
if (ctrlProp.Name == ExcelPropertyName &&
ctrlProp.PropertyType == typeof(String))
{
try
{
strReturn = (string)ctrlProp.GetValue(control, null);
break;
}
catch
{
strReturn = "";
}
}
if (ctrlProp.Name == ExcelPropertyName &&
ctrlProp.PropertyType == typeof(bool))
{
try
{
bReturn = (bool)ctrlProp.GetValue(control, null);
strReturn = bReturn ? "True" : "False";
break;
}
catch
{
strReturn = "Error";
}
}
if (ctrlProp.Name == ExcelPropertyName &&
ctrlProp.PropertyType == typeof(ListItem))
{
try
{
strReturn = ((ListItem)(ctrlProp.GetValue(control, null))).Text;
break;
}
catch
{
strReturn = "";
}
}
}
return strReturn;
}
}
Conclusion
In this article, we saw the technique for including HyperLink controls embedded in the GridView to be exported to Excel, along with other controls such as DropDownList and CheckBox. We also saw how to use Reflection to setup an extensible function to handle various control types.
Happy Coding!
Former memberPosted Sep 30, 2012, 1:14 PM
This is really nice article http://www.dotnetpools.com/Article/ArticleDetiail/?articleId=22&title=Gridview%20Export%20To%20Excel%20In%20Asp.Net%20C#
anisha praisyPosted Mar 21, 2011, 2:49 AM
Hi, I am exporting the gridview data to excel sheet from a webpage. The problem is while exporting, the whole page along with other controls are getting exported too to excel sheet, which is not desired. Any Help!!!
anisha praisyPosted Mar 21, 2011, 2:49 AM
Hi, I am exporting the gridview data to excel sheet from a webpage. The problem is while exporting, the whole page along with other controls are getting exported too to excel sheet, which is not desired. Any Help!!!
paul makramPosted Apr 15, 2009, 9:40 AM
error : RegisterForEventValidation can only be called during Render(); solution <%@ Page Language="C#" EnableEventValidation = "false" AutoEventWireup="true" CodeFile="ExportGridView.aspx.cs" Inherits="ExportGridView" %> http://geekswithblogs.net/azamsharp/archive/2005/12/21/63845.aspx
vishal bobbaPosted Mar 20, 2008, 11:08 AM
I used your code. It is working on some machines and on some machines while saving it is saving as document file type I couldnt figure it out what is wrong with mime type on those machines. Any Ideas? Thank you
Erick Rodriguez PlazaPosted Mar 12, 2008, 3:57 PM
Hi, your post is very interesting, but i also want to export my grid data to PDF. How can i do without 3 party components. I just were using Application/pdf, in Response.ContentType, but, i can not open the file.
Ettore CefalaPosted Jan 22, 2008, 12:11 PM
Sorry but this is just an HTML Export which Excel is just able to read. Never tried to export a few hundred records this way? Well, you'll discover that the exported data are very large and that Excel takes a lot of time to load them. If you need a real XML/XLSX Export to Excel you should try http://www.gridviewtoexcel.com. Regards
Shannon RosePosted Dec 5, 2007, 3:33 PM
Thank you so much for this. It's straightforward and complete! And most importantly, it works great! I shall look for more articles from you! :)
TonyPosted Dec 4, 2007, 1:04 PM
Hello, Thanks for the work. the code seems to work accordingly, but for some reason the only thing i get on the excel file is an open/close DIV tag i'm using it in a search page inside of a master page. any ideas? thanks for your response in advance
Alex StarrPosted Sep 19, 2007, 9:52 AM
Unfortunately, keep getting this exception even after implementing the suggestion from Part I. Please help!!
MahernozPosted Sep 11, 2007, 6:32 AM
Hi Dipal, First of all thanks for such an excellent article. However, i have now a different problem. I have exported my gridview to excel. Now i want to manually import my "generated" excel sheet to Google docs, so that I can share this "google spreadsheet" with other people. I am doing this... File->New after that i try "Import". I am getting the error: The Uploaded file could not be imported. I have also tried to upload it from my computer directly by clicking on "Upload" by it gives me the following message: "We're sorry, but we were unable to upload this document" and some steps such as Copy-Paste to do the same. I don't know, why i am not able to import the document directly. Do i need to make any changes in the encoding? I am using UTF 8 encoding while exporting my gridview as is written in this article. Please advice about the steps that i should take to make this possible. Regards, Mahernoz
hakeem kazmiPosted Sep 11, 2007, 2:54 AM
hi there,i am able to export the gridview data to excel sheet successfully but my gridview has 3 buttonfields like details etc etc which when clicked give the details,but i dont want those buttonfields to be in my excel sheet.plz help me.or alter the code below so that i can limit the columns to be exported to my excel sheet. protected void BtnExport_Click(object sender, EventArgs e) { string attachment = "attachment; filename=Contacts.xls"; Response.ClearContent(); Response.AddHeader("content-disposition", attachment); Response.ContentType = "application/ms-excel"; StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); this.ClearControls(devViewGrid1); devViewGrid1.RenderControl(htw); Response.Write(sw.ToString()); Response.End(); } public override void VerifyRenderingInServerForm(Control control) { } private void ClearControls(Control control) { for (int i = control.Controls.Count-1 ; i >= 0; i--) { ClearControls(control.Controls[i]); } if (!(control is TableCell)) { if (control.GetType().GetProperty("SelectedItem") != null) { LiteralControl literal = new LiteralControl(); control.Parent.Controls.Add(literal); try { literal.Text = (string)control.GetType().GetProperty("SelectedItem").GetValue(control, null); } catch { } control.Parent.Controls.Remove(control); } else if (control.GetType().GetProperty("Text") != null) { LiteralControl literal = new LiteralControl(); literal.Text = (string)control.GetType().GetProperty("Text").GetValue(control, null); if (literal.Text != "Top n") control.Parent.Controls.Add(literal); control.Parent.Controls.Remove(control); } return; } }
Alb mraPosted Aug 1, 2007, 1:09 PM
how I can save the xls file directly on server's hard drive without confirmation to send after by email?
kumar gPosted Jul 10, 2007, 8:14 AM
asdas
Jon PasketteditedPosted Jun 3, 2007, 2:04 PMEdited Jun 3, 2007, 9:32 PM
Dipal, This is an awesome article. I'm working in VB and converted Part II. The C# version works as advertised on my GridView with several checkboxes, but the VB version throws the RegisterForEventValidation can only be called during Render() error. I was willing to add the EnableEventValidation="false" but didn't know where to place it. I looked to see if there was a version on your VBDotNetHeaven site but found nothing. Can you point me in the direction of a working VB version? Thanks for your time. Jon
Marco AlencarPosted Apr 24, 2007, 8:11 AM
Hi Dipal, do you know when u send the form to Excel and it asks the user if he desires to open, save or cancel, is it possible to save it automatically without prompting a file download window? In other words...the Excel data would be automatically saved in a specified folder every time the user press "export to excel". Thanks
TTTTT OOOOOPosted Apr 11, 2007, 3:15 AM
Hi Dipal, I read both ur articles & I used the above code to Export my gridview to excel & word. I have paging & sorting set to true. I am facing 2 problems. (1) I get the error - I am using AJAX. Infact I am using an Anthem GirdView. This error got resolved when I turned the EventValidation to false. I think u mentioned in an article in Part 1 that this could be a security risk. Can u help me with this? (2) After the 1st problem is resolved temporarily, the next problem is that the entire DataSet doesn't get exported. Only the current page gets exported. I need paging, so is there a way where I can get the entire DataSet which is bound to the gridview control exported to both excel & word. Please help....Let me know if you need any of my code snippet. Thanks..
MikePosted Apr 3, 2007, 9:57 AM
This has worked perfectly for me. Thanks!