Extensive Study of GridView Export to Excel
By AzamSharp
Views: 43871

Introduction:

Exporting GridView to Excel is a very common task which is performed in most of the web applications. There are various techniques of exporting the GridView to excel and it highly depends on the application scenario. In this article I will demonstrate some techniques that you will find useful.

GridView Export the Excel (Basic Code): 

Let's start with the basic export scenario. First, we need to populate the GridView with some data. I have created a custom table which has number of fields. You can check out the screen shot below.

Now, the next task is to populate the GridView with the data from the database. Check out the following code which uses the DataSet to populate the GridView.

private void BindData()

{

SqlConnection myConnection = new SqlConnection("Server=localhost;Database=School;Trusted_Connection=true");

SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Users", myConnection);

DataSet ds = new DataSet();

ad.Fill(ds);

gvUsers.DataSource = ds;

gvUsers.DataBind();

}

So, now the GridView is populated with the data. The next task is to export the GridView to excel. You can use the following code for the button click event.

Response.ClearContent();

Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gvUsers.RenderControl(htw);

Response.Write(sw.ToString());

Response.End();

You will also need to override the VerifyRenderingInServerForm method. Take a look at the code below:

public override void VerifyRenderingInServerForm(Control control)

{

}

When you click the Export to Excel (Default) button a dialog box will popup which will allow you to open or save the exported file. Select open the file and you will see the exported data in the excel spreadsheet. Take a look at the screen shot below which shows the exported GridView in excel spreadsheet.

Exporting GridView to Excel With Style:

Did you see the problem in the above exportation code? Yes, the leading zero's were truncated. It means that if your ID was 000345 it will show up as 345. You can fix this problem by adding a CSS script to the output stream. In order for the ID column to appear correctly you need to store it as text. The text format in excel is represented by "mso-number-format:"\@". Once, you know the format you can append the style in the output stream. Check out the code below.

protected void Btn_ExportClick(object sender, EventArgs e)

{

string style = @"<style> .text { mso-number-format:\@; } </style> ";

Response.ClearContent();

Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gvUsers.RenderControl(htw);

// Style is added dynamically

Response.Write(style);

Response.Write(sw.ToString());

Response.End();

}

public override void VerifyRenderingInServerForm(Control control)

{

}

As, you can see in the above code that I have used the string variable "style" to hold the style of the GridView column. And I used the Response.Write method to write the style to the output stream. The last thing that you need to do is to add the style to the ID column. This can be done in the RowDataBound event of the GridView control.

protected void gvUsers_RowDataBound(object sender, GridViewRowEventArgs e)

{

if (e.Row.RowType == DataControlRowType.DataRow)

{

e.Row.Cells[1].Attributes.Add("class", "text");

}

}

 Now, when you export the GridView to excel your exported file will look something like this.

Finding Style For the Column

You can easily find the correct style for your GridView column by opening the exported excel file. Now, click on the column header and select "Format Cells". This will present you with several options to format the cells. Select text from the list and save the file as .htm (webpage) file. Now, open the webpage in your browser and view the source. In the style section you will find different styles for the table cell (td element). Now, locate the ID column by doing a search on the source of the webpage. You will find a line like this:

<td class=xl27 width=35 style='border-left:none;width:26pt'>ID</td>
As, you can see that the above table cell uses the class x127. Now, go to the styles section and find the x127. 
.xl27
{mso-style-parent:style0;
font-weight:700;
mso-number-format:"\@";
text-align:center;
vertical-align:middle;
border:.5pt solid black;
white-space:normal;}
When you look up the .x127 you will find the format of the cell defined as mso-number-format:"\@";.  

Exporting GridView With LinkButtons and Paging: 

When you try to export the GridView which contains LinkButtons and Paging enabled then you might see the following error.

You can easily handle this error by going to the page source and turning the EnableEventValidation = "false".

<%@ Page Language="C#" EnableEventValidation="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

But let's take a look at the exported file.

As, you can see that the LinkButtons and DropDownLists are also exported with the GridView control. Although the DropDownList does display the correct user selections but it does not look good in the exported file. So, let's see how we can remove the DropDownList and only display the selected text.

I have created a simple DisableControls method which iterates through the GridView control and replace all LinkButtons and DropDownLists with the Literal control.

private void DisableControls(Control gv)

{

LinkButton lb = new LinkButton();

Literal l = new Literal();

string name = String.Empty;

for (int i = 0; i < gv.Controls.Count; i++)

{

if (gv.Controls[i].GetType() == typeof(LinkButton))

{

l.Text = (gv.Controls[i] as LinkButton).Text;

gv.Controls.Remove(gv.Controls[i]);

gv.Controls.AddAt(i, l);

}

else if (gv.Controls[i].GetType() == typeof(DropDownList))

{

l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text;

gv.Controls.Remove(gv.Controls[i]);

gv.Controls.AddAt(i, l);

}

 

if (gv.Controls[i].HasControls())

{

DisableControls(gv.Controls[i]);

}

}

}

The idea is very simple just replace all the LinkButton and DropDownList controls with a Literal control and assign their selection to the Literal control Text property. You need to call this function before the exportation takes place.

protected void Btn_ExportExcelPaging(object sender, EventArgs e)

{

DisableControls(gvUsers);

Response.ClearContent();

Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gvUsers.RenderControl(htw);

Response.Write(sw.ToString());

Response.End();

}

Now, when you export the GridView you will only see the selected text. Check out the screen shot below which shows the effect.

Conclusion:

In this article you learned different ways to export the GridView to excel. I have attached the complete source code to download. I hope you liked this article, happy coding!


By AzamSharp




Enter Comment/Feedback
  •  
  •  
  •  
  •  
  •  

Comments/Feedbacks
Subject: GridView Export to Excel, Visual Basic Version?
Name: Arif Ali
Date: 1/30/2007 10:10:51 AM
Comment:
I tried to convert this to VB and am getting stuck on the prerendering; i.e., the conversion of checkbox fields, etc. Can you provide a VB version?

Thanks,
Subject: How to get Excel in multiple spread sheets
Name: Deepak
Date: 2/16/2007 2:00:12 AM
Comment:
Hi ,

The article is superb and is working fine, but i face a problem in exporting large data. My requirement is when the data exeeds max rows of excel (65000) the rest of the data should go to a separate sheet in the same excel file.
Please help me in this regard. Kindly mail me to mace_deepak@yahoo.com. Its very urgent for me...
Subject: Re: Exporting Large Data
Name: AzamSharp
Date: 2/17/2007 8:45:50 PM
Comment:
Deepak, you might need to use the Office Libraries in order to export the data into different sheets. I think you can make reference to those libraries using the COM reference.
Subject: Still not keeping zeros
Name: Ron
Date: 2/20/2007 10:32:27 AM
Comment:
Here is my code. I still am missing leading zeros. Can you please help? Thank you in advance.


protected void btnExcel_Click(object sender, EventArgs e)
{
string style = @" ";
gvPartsByVS.DataSource = Session["Parts"];
gvPartsByVS.DataBind();
gvPartsByVS.Font.Size = 8;
gvPartsByVS.Columns[3].ItemStyle.HorizontalAlign = HorizontalAlign.Left;
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
Response.ContentType = "application/excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gvPartsByVS.RenderControl(htw);
Response.Write(style);
Response.Write(sw.ToString());
Response.End();
}

public override void VerifyRenderingInServerForm(Control control)
{

}

protected void btnGoBack_Click(object sender, EventArgs e)
{
Response.Redirect("SelectVS.aspx");
}

protected void gvPartsByVS_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[3].Attributes.Add("class", "text");
}
}
Subject: Well Done Keep the GOdd Things Going on
Name: Kamran Bhatti
Date: 3/1/2007 4:26:15 AM
Comment:
Great Article Very Well,and thanks
Subject: Excellent article
Name: Naga Raja Sharma
Date: 3/1/2007 2:19:44 PM
Comment:
This is the best article on excel exporting. The problems discussed are most common and the solution given is is great. Keep up the good work.....
Subject: error when used with ATLAS
Name: paul
Date: 3/7/2007 5:31:12 PM
Comment:

Hi,

I used this example and it all worked fine until I added a HoverMenu Control into the gridview, I now get the error pasted below.

any ideas??



Extender control 'hme3' is not a registered extender control. Extender controls must be registered using RegisterExtenderControl() before calling RegisterScriptDescriptors().
Parameter name: extenderControl
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: Extender control 'hme3' is not a registered extender control. Extender controls must be registered using RegisterExtenderControl() before calling RegisterScriptDescriptors().
Parameter name: extenderControl

Source Error:

Line 44: HtmlTextWriter htw = new HtmlTextWriter(sw);
Line 45:
Line 46: GridView1.RenderControl(htw);
Line 47:
Line 48: Response.Write(sw.ToString());


Subject: error when used with ATLAS
Name: AzamSharp
Date: 3/12/2007 8:46:01 PM
Comment:
Hi,

Try using the control outside the GridView. It may be because of the settings of the extender control like using the script manager.
Subject: Good Stuff
Name: linn
Date: 3/27/2007 5:53:35 PM
Comment:
Thanks for the very clear illustration of the whole exporting logic, especially the part on error handling. I got everything to work in just 5 mins! :o)
Subject: Links for sorting columns remain
Name: JD
Date: 4/5/2007 3:02:53 PM
Comment:
Great help, the part on disabling controls really cleaned up the spreadsheet. One question though, the links created in the header cells when sorting is enabled in the gridview remain after calling DisableControls? I had solved this issue previously by setting the AllowSorting property of the gridview to false and rebinding before rendering it to the HtmlTextWriter. Wanting to remove unnecessary code and thinking DisableControls would take care of the headers as well, I was surprised to see the links persist in the spreadsheet.

I know I can just implement my previous code but was wondering if you had an explanation for this, would testing for a data type in addition to LinkButton make DisableControls into the catchall solution?
Subject: Good Stuff
Name: Sam
Date: 4/13/2007 7:56:24 AM
Comment:
Worked like a charm. Thanks!
Subject: export more than one GridView to the same excel workbook but seperate worksheets
Name: eric francois
Date: 4/17/2007 11:29:43 AM
Comment:
need to know possibilities for exporting say 3 GridViews on one .aspx page into one excel workbook but each GridView is placed on its own worksheet inside that workbook. So, final result is one workbook (.xls) with 3 worksheet inside of it.

any suggestion will be greatly appreciated!
Subject: GridView Export to Excel, using themes