Export a GridView to Excel – C#

Posted by rameshch on July 10, 2008

when exporting excel in grid view am getting this error

System.Web.HttpException: Control ‘grdReport’ of type ‘GridView’ must be placed inside a form tag with runat=server.  and

RegisterForEventValidation can only be called during Render();

 The line: grdReport.RenderControl(htw); is tagged as the culprit. The original gridview is in a form tag with runat=server.

 my solution as follows

<%@ Page Language="C#" AutoEventWireup="true" Codebehind="GridViewExport.aspx.cs"
    Inherits="ForForums.GridViewExport" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="CompanyListGridView" AutoGenerateColumns="false" CellPadding="3"
                CellSpacing="1" HeaderStyle-HorizontalAlign="Left" RowStyle-VerticalAlign="top"
                AlternatingRowStyle-VerticalAlign="top" RowStyle-BackColor="Lavender" AlternatingRowStyle-BackColor="LightBlue"
                HeaderStyle-BackColor="#006699" HeaderStyle-ForeColor="White" BorderStyle="None"
                BackColor="Black" GridLines="None" EmptyDataRowStyle-BackColor="Lavender" EmptyDataText="No records found."
                OnRowCreated="OnRowCreated" runat="server">
                <Columns>
                    <asp:BoundField DataField="CompanyName" ItemStyle-Width="300px" />
                </Columns>
            </asp:GridView>
            <br />
            <br />
            <asp:Button ID="Button1" runat="server" Text="Export" OnClick="Button1_Click" />
        </div>
    </form>
</body>
</html>
GridViewExport.aspx.cs:
 
using System;
using System.Data;
using System.Data.Common;
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 Microsoft.Practices.EnterpriseLibrary.Data;

namespace ForForums
{
    public partial class GridViewExport : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Database db = DatabaseFactory.CreateDatabase();
                LoadCompanyList(db);
            }

        }

        protected void LoadCompanyList(Database db)
        {
            CompanyListGridView.DataSource = CompanyManager.GetCompanies(db);
            CompanyListGridView.DataBind();
        }

        protected void OnRowCreated(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
                foreach (TableCell headerCell in e.Row.Cells)
                    headerCell.Text = "Company Name";
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            GridViewExportUtil.Export("Companies.xls", this.CompanyListGridView);
        }
    }
}

 

 

And a class file, GridViewExport.cs :

 

using System;
using System.Data;
using System.Configuration;
using System.IO;
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;

public class GridViewExportUtil
{

    public static void Export(string fileName, GridView gv)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader(
            "content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";

        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                //  Create a form to contain the grid
                Table table = new Table();

                //  add the header row to the table
                if (gv.HeaderRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
                    table.Rows.Add(gv.HeaderRow);
                }

                //  add each of the data rows to the table
                foreach (GridViewRow row in gv.Rows)
                {
                    GridViewExportUtil.PrepareControlForExport(row);
                    table.Rows.Add(row);
                }

                //  add the footer row to the table
                if (gv.FooterRow != null)
                {
                    GridViewExportUtil.PrepareControlForExport(gv.FooterRow);
                    table.Rows.Add(gv.FooterRow);
                }

                //  render the table into the htmlwriter
                table.RenderControl(htw);

                //  render the htmlwriter into the response
                HttpContext.Current.Response.Write(sw.ToString());
                HttpContext.Current.Response.End();
            }
        }
    }

    /// <summary>
    /// Replace any of the contained controls with literals
    /// </summary>
    /// <param name="control"></param>
    private static void PrepareControlForExport(Control control)
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control current = control.Controls[i];
            if (current is LinkButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
            }
            else if (current is ImageButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
            }
            else if (current is HyperLink)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
            }
            else if (current is DropDownList)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
            }
            else if (current is CheckBox)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
            }

            if (current.HasControls())
            {
                GridViewExportUtil.PrepareControlForExport(current);
            }
        }
    }
}

One Response to “Export a GridView to Excel – C#”

  1. [...] by rameshch on July 30, 2008 In previous post (Export a GridView to Excel - C#)  am unable to add different colors to head and [...]

Leave a Reply

You must be logged in to post a comment.