Publicado en .NET, ASP.NET, C#, VB

Mini: Cómo exportar GridView a Excel? ASP.NET


En este mini-post explico cómo es posible exportar un control GridView(El cuál en html se traduce al tag <table></table>).

1 – Tenemos la siguiente ASPX:


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExportGridView.aspx.cs" Inherits="testsl.Web.ExportGridView" %>

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true">
        </asp:GridView>
    </div>
    <asp:Button ID="Button1" runat="server" Text="Exportar" 
        onclick="Button1_Click" />
    </form>
</body>
</html>

2 – En pantalla se verá de la siguiente forma:

3 -El code-behind queda de la siguiente forma. Allí el método ExportToExcel permite hacer lo correspondiente a generar un archivo tipo .xls . Observece la clase Person, va a ser el tipo de datos de la colección List que va a servir de fuente de datos para el objeto GridView.

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Web.UI.HtmlControls;
using System.Text;

namespace testsl.Web
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Pais { get; set; }
    }
    public partial class ExportGridView : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                List<Person> personas = new List<Person>();
                personas.Add(new Person { Id = 1, Name = "Jose", Pais = "Uruguay" });
                personas.Add(new Person { Id = 2, Name = "Pedro", Pais = "Venezuela" });
                personas.Add(new Person { Id = 3, Name = "Antonio", Pais = "Chile" });
                personas.Add(new Person { Id = 4, Name = "Mario", Pais = "Ecuador" });
                personas.Add(new Person { Id = 5, Name = "Juan", Pais = "México" });
                personas.Add(new Person { Id = 6, Name = "Felipe", Pais = "Colombia" });
                GridView1.DataSource = personas;
                GridView1.DataBind();
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            ExportToExcel("Informe.xls", GridView1);
        }

        private  void ExportToExcel(string nameReport, GridView wControl)
        {
            HttpResponse response = Response;
            StringWriter sw = new StringWriter();
            HtmlTextWriter htw = new HtmlTextWriter(sw);
            Page pageToRender = new Page();
            HtmlForm form = new HtmlForm();
            form.Controls.Add(wControl);
            pageToRender.Controls.Add(form);
            response.Clear();
            response.Buffer = true;
            response.ContentType = "application/vnd.ms-excel";
            response.AddHeader("Content-Disposition", "attachment;filename=" + nameReport);
            response.Charset = "UTF-8";
            response.ContentEncoding = Encoding.Default;
            pageToRender.RenderControl(htw);
            response.Write(sw.ToString());
            response.End();
        }
    }
   
}

VB


Imports System.IO

Public Class GridViewToExcel
    Inherits System.Web.UI.Page

    Private Sub GridViewToExcel_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Dim personas As New List(Of Person)()
            personas.Add(New Person() With { _
             .Id = 1, _
             .Name = "Jose", _
             .Pais = "Uruguay" _
            })
            personas.Add(New Person() With { _
             .Id = 2, _
             .Name = "Pedro", _
             .Pais = "Venezuela" _
            })
            personas.Add(New Person() With { _
             .Id = 3, _
             .Name = "Antonio", _
             .Pais = "Chile" _
            })
            personas.Add(New Person() With { _
             .Id = 4, _
             .Name = "Mario", _
             .Pais = "Ecuador" _
            })
            personas.Add(New Person() With { _
             .Id = 5, _
             .Name = "Juan", _
             .Pais = "México" _
            })
            personas.Add(New Person() With { _
             .Id = 6, _
             .Name = "Felipe", _
             .Pais = "Colombia" _
            })
            GridView1.DataSource = personas
            GridView1.DataBind()
        End If
    End Sub

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        ExportToExcel("Informe.xls", GridView1)
    End Sub

    Private Sub ExportToExcel(ByVal nameReport As String, ByVal wControl As GridView)
        Dim responsePage As HttpResponse = Response
        Dim sw As New StringWriter()
        Dim htw As New HtmlTextWriter(sw)
        Dim pageToRender As New Page()
        Dim form As New HtmlForm()
        form.Controls.Add(wControl)
        pageToRender.Controls.Add(form)
        responsePage.Clear()
        responsePage.Buffer = True
        responsePage.ContentType = "application/vnd.ms-excel"
        responsePage.AddHeader("Content-Disposition", "attachment;filename=" & nameReport)
        responsePage.Charset = "UTF-8"
        responsePage.ContentEncoding = Encoding.Default
        pageToRender.RenderControl(htw)
        responsePage.Write(sw.ToString())
        responsePage.End()
    End Sub

   
End Class

Public Class Person

    Private _id As Integer
    Public Property Id() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            _id = value
        End Set
    End Property

    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _pais As String
    Public Property Pais() As String
        Get
            Return _pais
        End Get
        Set(ByVal value As String)
            _pais = value
        End Set
    End Property

End Class

Como se vé básicamente el método permite generar un response embebiendo el codigo html hacia el cliente con el contentType application/vnd.ms-excel esto y a través de definir la extensión como .xls permite generar un archivo de tipo excel , el cual si lo abrimos quedará se la siguiente forma.

Autor:

Soy desarrollador de software .NET con experiencia en ASP.NET, ASP.NET MVC, Silverlight, WCF RIA, WPF, C#, SQL Server.

40 comentarios sobre “Mini: Cómo exportar GridView a Excel? ASP.NET

  1. wenisimo el tip

    solo te comento q tuve agregar esto:
    using System.IO;
    using System.Text;

    al cod de la pagina y funciono todo ok.

    ojala que a alguien mas le sirva

  2. muchas gracias, tuve un inconveniente por que utilizo un link button dentro de un template field y se sacaba un error
    «El control ‘grdvFiltro_ctl08_LinkButton2’ de tipo ‘LinkButton’ debe colocarse dentro de una etiqueta de formulario con runat=server.»

    la solucion que implemente fue crear otro gridview pero sin template fields, lo lleno al momento de exportar a excel (click de un boton) y asi no me genero errores por runat server.

  3. El error que indica Mario Andrés también puede desencadenarse si el GridView tiene la propieda ‘Allow Sorting’ activada, ya que crea enlaces en los títulos de la tabla.

  4. Yo tengo un gridview que le añadido la funcionalidad de mostrar subtotales por grupo, pero cuando lo exporto a excel salen incompletos los datos y no salen los subtotales. Alguna idea?

    1. Enmarca todo los controles asp en un asp panel (aquellos controles que sean importantes para el informe), porterior a esto, tienes que modificar el metodo, para que lo que se exporte sea el panel, también es importante recordar que cuando se hace click en el botón de excel, ocurre un postack, por ahí se deba volver a setear el valor de los controles que presentan los subtotales.

      Saludos espero sirva!

  5. muy bueno, pero me saca un error o advertencia a la hora de quererlo abrir. me dice: «el archivo que intenta abrir ‘shalala.xls’, tiene otro formato que el especificado por la extension del archivo. compruebe que el archivo no este dañado y que procede de un origen de confianza.etc, etc » y ya le doy que si quiero abrir y lo abre normal,al igual al de guardar me saca otra vez eso ,pero me gustaria quitarle este aviso, y no he encontrado una mejor explicacion que esta, no se si tuvieras alguna manera de corregir esto plis…
    saludos !!!!

  6. Un año después de tu publicación… te digo que me salió perfecto, mil gracias.
    Sólo que cuando lo abro me sale una ventana emergente y debo darle Sí para que abra el archivo.
    De todas formas, mil gracias, muy útil.

  7. Hola, la solucion al problema del runat server se soluciona colocando esta linea…

    public override void VerifyRenderingInServerForm(Control control)
    { }
    Saludos

  8. no me sirvio , me sale con codigo HTML que hagoooo??

    » <table" cellspacing="0" rules="all" border="1"
    " »
    » 10/1/2012 2:09:22 PMES51Repuestos

  9. Oigan alguien sabe que son wControl nameReport xq marca como que no los encuentra soy nuevo en esto y pues ademas yo ya tengo mi fuente de datos solo quiero el codigo del boton no se si me sirba para este caso

  10. no me salio…en c# 2010…tengo otra pero cuando voy al iss no me sale..
    ystem.Diagnostics.Process.Start(String.Format(«{0}\\{1}.xls», Server.MapPath(null), «Reporte_ParteDiario»));

  11. Estimado: Tengo un pequeño problema, yo también hago un excel al vuelo, y no tengo problemas en entregarselo al cliente. PEEERO, cuando se trata de archivos de alto peso (unos 70mb), me gustaría poder comprimirlo antes de enviarselo al cliente… ¿se puede hacer eso? he intentado grabar el xls primero al disco del servidor para así después comprimir, pero no me resulta escribir el archivo en el disco!

  12. Tengo un pequeño problema, sale este error:
    «Sólo se puede llamar a RegisterForEventValidation durante Render();»
    ya intente con varias paso, pero no he logrado mi objetivo.
    Espero su pronta ayuda.
    Gracias y saludos.

  13. Buen dia tengo un problema este codigo me da error al declarar Dim pageToRender As New Page() yo estoy en vb.net y me dice que PAGE es de asp.net como puedo hacer alli

  14. Funciona si lo haces en un ASPX normal.
    Sin embargo, cuando metes el mismo codigo dentro del UpdatePanel que a su vez esta dentro de una MasterPage… el mismo da error.

    Yo lo solucione asi: Donde Button1 es el ID del boton q larga el evento de exportar.
    ScriptManager scripManager = ScriptManager.GetCurrent(this.Page);
    scripManager.RegisterPostBackControl(Button1);

  15. QUE TAL AMIGOS. TENGO UN PEQUEÑO PROBLEMA CON EL CODIGO QUE NOS COMPARTEN, ES DE NOTAR QUE EL CODIGO FUNCIONA PERFECTAMENTE PERO CUANDO EL ARCHIVO SE VA A EXPORTAR CON UN MAYOR PESO SE ABRE DIRECTAMENTE EN WORD, COMO SE PODRA SOLUCCIONAR ESTE PROBLEMA. MUCHAS GRACIAS POR SU COLABORACION……….

Replica a fernandoingunza Cancelar la respuesta