Te pongo el codigo de una clase que uso para exportar a excel grids, lo que pasa cuando son TemplateColumns es que hay que quitar el Template y asignarle un objeto Literal para que lo ponga como texto:
Código:
Imports System
Imports System.Data
Imports System.Configuration
Imports System.IO
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Public Class GridViewExportUtil
Public Shared Function Export(ByVal gv As GridView) As String
HttpContext.Current.Response.Clear()
Dim sw As StringWriter = New StringWriter
Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
' Create a form to contain the grid
Dim table As Table = New Table
With table
.GridLines = gv.GridLines
.Width = gv.Width.Value
End With
'AGREGANDO EL HEADER.
If Not (gv.HeaderRow Is Nothing) Then
GridViewExportUtil.PrepareControl*****port(gv.HeaderRow)
With gv.HeaderRow
.Cells(gv.Columns.Count - 1).Visible = False 'kitando la ultima KOLUMNA DEL HEADER
.HorizontalAlign = HorizontalAlign.Center
.BackColor = Drawing.ColorTranslator.FromHtml("#4A3C8C")
.ForeColor = Drawing.Color.White
End With
table.Rows.Add(gv.HeaderRow)
End If
' add each of the data rows to the table
For Each row As GridViewRow In gv.Rows
GridViewExportUtil.PrepareControl*****port(row)
With row
.BackColor = Drawing.ColorTranslator.FromHtml("#E7E7FF")
.ForeColor = Drawing.ColorTranslator.FromHtml("#4A3C8C")
.Cells(gv.Columns.Count - 1).Visible = False
'.BorderWidth = 1
.HorizontalAlign = HorizontalAlign.Center
'.Font.Bold = True
'<AlternatingRowStyle BackColor="#F7F7F7" />
'<RowStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" />
End With
table.Rows.Add(row)
Next
'AGREGANDO EL footer.
If Not (gv.FooterRow Is Nothing) Then
GridViewExportUtil.PrepareControl*****port(gv.FooterRow)
With gv.FooterRow
.Cells(gv.Columns.Count - 1).Visible = False 'kitando la ultima KOLUMNA DEL HEADER
.HorizontalAlign = HorizontalAlign.Center
.BackColor = Drawing.ColorTranslator.FromHtml("#B5C7DE")
.ForeColor = Drawing.ColorTranslator.FromHtml("#4A3C8C")
.Font.Bold = True
End With
table.Rows.Add(gv.FooterRow)
End If
' render the table into the htmlwriter
table.BorderWidth = 2
table.RenderControl(htw)
Export = sw.ToString
End Function
' Replace any of the contained controls with literals
Private Shared Sub PrepareControl*****port(ByVal control As Control)
Dim i As Integer = 0
Do While (i < control.Controls.Count)
Dim current As Control = control.Controls(i)
If (TypeOf current Is LinkButton) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is ImageButton) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is HyperLink) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is DropDownList) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is CheckBox) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is RadioButton) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is TextBox) Then
control.Controls.Remove(current)
control.Controls.AddAt(i, New LiteralControl(CType(current, TextBox).Text))
ElseIf (TypeOf current Is RegularExpressionValidator) Then
control.Controls.Remove(current)
ElseIf (TypeOf current Is Button) Then
control.Controls.Remove(current)
End If
If current.HasControls Then
GridViewExportUtil.PrepareControl*****port(current)
End If
i = (i + 1)
Loop
End Sub
End Class
Te explico mas o menos como funciona, a la funcion Export es a la que le pasas el DG a exportar, el Sub PrepareControl*****port se encarga de quitar los Controles que tengas en cada celda y remplazarlo por su valor en texto. Espero te sirva. Saludos.