In this article I will explain with an example, how to export TemplateField columns of the ASP.Net GridView control to Excel file in ASP.Net using C# and VB.Net.
When the GridView TemplateField columns contain controls like HyperLink, TextBox, Button, LinkButton, RadioButton or CheckBox controls then such controls need to be replaced with Literal control and then the GridView is exported to Excel file in ASP.Net using C# and VB.Net.
 
 
Database
Here I am making use of Microsoft’s Northwind Database. You can download it from here.
 
 
HTML Markup
The HTML Markup consists of an ASP.Net GridView control and a Button.
For the GridView paging has been enabled using the AllowPaging property and the OnPageIndexChanging event has been assigned.
The GridView consists of some TemplateField Columns with different controls like HyperLink, TextBox, Button, LinkButton, RadioButton and CheckBox for illustration purposes.
<asp:GridView ID="GridView1" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White"
    RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000"
    runat="server" AutoGenerateColumns="false" AllowPaging="true" OnPageIndexChanging="OnPageIndexChanging">
    <Columns>
        <asp:BoundField DataField="ContactName" HeaderText="Contact Name" ItemStyle-Width="150px" />
        <asp:TemplateField HeaderText="City">
            <ItemTemplate>
                <asp:HyperLink ID="lnkCity" runat="server" NavigateUrl="#" Text='<%# Eval("City") %>'></asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Country">
            <ItemTemplate>
                <asp:TextBox ID="txtCountry" runat="server" Text='<%# Eval("Country") %>'></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Country">
            <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server" Text = "CheckBox Control" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Country">
            <ItemTemplate>
                <asp:RadioButton ID="RadioButton1" runat="server" Text = "RadioButton Control" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<br />
<asp:Button ID="btnExport" runat="server" Text="Export To Excel" OnClick="ExportToExcel" />
 
 
Namespaces
You will need to import the following namespaces.
C#
using System.IO;
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;
 
VB.Net
Imports System.IO
Imports System.Data
Imports System.Drawing
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Collections.Generic
 
 
Populating the GridView control
Inside the Page Load event, the GridView is populated with records from the Customers Table of the Northwind Database.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        this.BindGrid();
    }
}
 
private void BindGrid()
{
    string strConnString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.Connection = con;
                sda.SelectCommand = cmd;
                using (DataTable dt = new DataTable())
                {
                    sda.Fill(dt);
                    GridView1.DataSource = dt;
                    GridView1.DataBind();
                }
            }
        }
    }
}
 
VB.Net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Me.BindGrid()
    End If
End Sub
 
Private Sub BindGrid()
    Dim strConnString As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As New SqlConnection(strConnString)
        Using cmd As New SqlCommand("SELECT * FROM Customers")
            Using sda As New SqlDataAdapter()
                cmd.Connection = con
                sda.SelectCommand = cmd
                Using dt As New DataTable()
                    sda.Fill(dt)
                    GridView1.DataSource = dt
                    GridView1.DataBind()
                End Using
            End Using
        End Using
    End Using
End Sub
 
 
Implementing Paging in GridView
The OnPageIndexChanging event handles the Pagination in the GridView.
Inside the OnPageIndexChanging event handler, the GridView’s PageIndex property is updated and the GridView is again populated from Database by making call to the BindGrid method.
C#
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    this.BindGrid();
}
 
VB.Net
Protected Sub OnPageIndexChanging(sender As Object, e As GridViewPageEventArgs)
    GridView1.PageIndex = e.NewPageIndex
    Me.BindGrid()
End Sub
 
 
Exporting GridView with TemplateField controls to Excel
When the Export Button is clicked, first the Content Type is set in the Response Stream in order to specify the Browser that the downloading file is an Excel file.
The Paging is disabled for the GridView by setting the AllowPaging property to False and the GridView is again populated with records from the Database.
Then a loop is executed over the GridView rows and the style and formatting are applied to the Row and Alternating Row of the GridView control.
Note: The colors are applied to individual cell of each Row and not to the whole Row as if this is not done then the color will spread on all cells of the Excel sheet.
 
CSS class named textmode is applied to each cell of the GridView. This class makes sure that all the contents are rendered in Text format (mso number format).
Note: The mso number format style prevents large numbers from getting converted to exponential values.
 
Now another loop is executed over Controls present inside the GridView using a SWITCH-CASE statement the value of each control is extracted and the control is replaced with a Literal control.
C#
protected void ExportToExcel(object sender, EventArgs e)
{
    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls");
    Response.Charset = "";
    Response.ContentType = "application/vnd.ms-excel";
    using (StringWriter sw = new StringWriter())
    {
        HtmlTextWriter hw = new HtmlTextWriter(sw);
 
        //To Export all pages
        GridView1.AllowPaging = false;
        this.BindGrid();
 
        GridView1.HeaderRow.BackColor = Color.White;
        foreach (TableCell cell in GridView1.HeaderRow.Cells)
        {
            cell.BackColor = GridView1.HeaderStyle.BackColor;
        }
        foreach (GridViewRow row in GridView1.Rows)
        {
            row.BackColor = Color.White;
            foreach (TableCell cell in row.Cells)
            {
                if (row.RowIndex % 2 == 0)
                {
                    cell.BackColor = GridView1.AlternatingRowStyle.BackColor;
                }
                else
                {
                    cell.BackColor = GridView1.RowStyle.BackColor;
                }
                cell.CssClass = "textmode";
                List<Control> controls = new List<Control>();
 
                //Add controls to be removed to Generic List
                foreach (Control control in cell.Controls)
                {
                    controls.Add(control);
                }
 
                //Loop through the controls to be removed and replace with Literal
                foreach (Control control in controls)
                {
                    switch (control.GetType().Name)
                    {
                        case "HyperLink":
                            cell.Controls.Add(new Literal { Text = (control as HyperLink).Text });
                            break;
                        case "TextBox":
                            cell.Controls.Add(new Literal { Text = (control as TextBox).Text });
                            break;
                        case "LinkButton":
                            cell.Controls.Add(new Literal { Text = (control as LinkButton).Text });
                            break;
                        case "CheckBox":
                            cell.Controls.Add(new Literal { Text = (control as CheckBox).Text });
                            break;
                        case "RadioButton":
                            cell.Controls.Add(new Literal { Text = (control as RadioButton).Text });
                            break;
                    }
                    cell.Controls.Remove(control);
                }
            }
        }
 
        GridView1.RenderControl(hw);
           
        //style to format numbers to string
        string style = @"<style> .textmode { } </style>";
        Response.Write(style);
        Response.Output.Write(sw.ToString());
        Response.Flush();
        Response.End();
    }
}
 
public override void VerifyRenderingInServerForm(Control control)
{
    /* Verifies that the control is rendered */
}
 
VB.Net
Protected Sub ExportToExcel(sender As Object, e As EventArgs)
    Response.Clear()
    Response.Buffer = True
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls")
    Response.Charset = ""
    Response.ContentType = "application/vnd.ms-excel"
    Using sw As New StringWriter()
        Dim hw As New HtmlTextWriter(sw)
 
        'To Export all pages
        GridView1.AllowPaging = False
        Me.BindGrid()
 
        GridView1.HeaderRow.BackColor = Color.White
        For Each cell As TableCell In GridView1.HeaderRow.Cells
            cell.BackColor = GridView1.HeaderStyle.BackColor
        Next
        For Each row As GridViewRow In GridView1.Rows
            row.BackColor = Color.White
            For Each cell As TableCell In row.Cells
                If row.RowIndex Mod 2 = 0 Then
                    cell.BackColor = GridView1.AlternatingRowStyle.BackColor
                Else
                    cell.BackColor = GridView1.RowStyle.BackColor
                End If
                cell.CssClass = "textmode"
                Dim controls As New List(Of Control)()
 
                'Add controls to be removed to Generic List
                For Each control As Control In cell.Controls
                    controls.Add(control)
                Next
 
                'Loop through the controls to be removed and replace with Literal
                For Each control As Control In controls
                    Select Case control.GetType().Name
                        Case "HyperLink"
                            cell.Controls.Add(New Literal() With { _
                             .Text = TryCast(control, HyperLink).Text _
                            })
                            Exit Select
                        Case "TextBox"
                            cell.Controls.Add(New Literal() With { _
                             .Text = TryCast(control, TextBox).Text _
                            })
                            Exit Select
                        Case "LinkButton"
                            cell.Controls.Add(New Literal() With { _
                             .Text = TryCast(control, LinkButton).Text _
                            })
                            Exit Select
                        Case "CheckBox"
                            cell.Controls.Add(New Literal() With { _
                             .Text = TryCast(control, CheckBox).Text _
                            })
                            Exit Select
                        Case "RadioButton"
                            cell.Controls.Add(New Literal() With { _
                             .Text = TryCast(control, RadioButton).Text _
                            })
                            Exit Select
                    End Select
                    cell.Controls.Remove(control)
                Next
            Next
        Next
 
        GridView1.RenderControl(hw)
 
        'style to format numbers to string
        Dim style As String = "<style> .textmode { } </style>"
        Response.Write(style)
        Response.Output.Write(sw.ToString())
        Response.Flush()
        Response.End()
    End Using
End Sub
 
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
    ' Verifies that the control is rendered
End Sub
 
 
Screenshots
The GridView with controls inside TemplateField columns
Export ASP.Net GridView with TemplateField Column to Excel after removing controls like HyperLink, TextBox and Button
 
The exported Excel File
Export ASP.Net GridView with TemplateField Column to Excel after removing controls like HyperLink, TextBox and Button
 
 
Demo
 
 
Downloads