Pregunta

¿Cuál es la mejor manera de exportar una vista de cuadrícula a una hoja de cálculo de Excel? Esto parece fácil

excepto que mi Gridview no tiene un atributo de exportación. ¿Cuál es la forma más rápida de hacer esto?

¿Fue útil?

Solución

En una exportación a Excel Escriba este código en el evento btnexporttoExcel Click.

    string attachment = "attachment; filename=Export.xls";

    Response.ClearContent();

    Response.AddHeader("content-disposition", attachment);

    Response.ContentType = "application/ms-excel";

    StringWriter sw = new StringWriter();

    HtmlTextWriter htw = new HtmlTextWriter(sw);

    // Create a form to contain the grid

    HtmlForm frm = new HtmlForm();

   gv.Parent.Controls.Add(frm);

    frm.Attributes["runat"] = "server";

    frm.Controls.Add(gv);

    frm.RenderControl(htw);



    //GridView1.RenderControl(htw);

    Response.Write(sw.ToString());

    Response.End();

Otros consejos

Probablemente haya algo por ahí para esto, pero si quieres hacerlo tú mismo, puedes escribir un código que recorre la colección GridView.Rows y luego la colección GridViewRow.Cells dentro de eso.

Debería ser bastante fácil construir un archivo CSV desde allí, y Excel podría leerlo sin problemas.

Los archivos CSV son solo archivos de texto con valores dentro de comillas, separados por comas. Así:

"value", "value", "value"
"value", "value", "value"

Puede abrir el Bloc de notas y abrir uno a mano para probarlo.

He hecho esto varias veces. Excel tiene una versión XML. Termina con la extensión .xml, pero puede cambiar la extensión del archivo a .xls y el archivo con formato XML se abrirá en Excel muy bien.

El mayor obstáculo de este enfoque es el formato XML excel. Generalmente creo un archivo de Excel en Excel en el formato aproximado que deseo. Luego guardo el archivo de Excel en formato XML y lo abro en un editor de texto.

Normalmente creo un archivo de plantilla desde esta página de muestra de Excel. Luego, cuando estoy exportando la información en la Vista de cuadrícula, solo tengo que crear el xml para la sección que contiene las celdas que planeo rellenar, solo tengo que adjuntar y adjuntar el texto ya en el archivo de plantilla.

Una vez que abra el archivo Excel con formato xml, descubrirá el XML necesario con relativa facilidad. La parte más difícil de entender es la forma en que las celdas hacen referencia a las opciones de formato, que se encuentran en la parte superior del archivo XML.

Buena suerte, avísame si necesitas más aclaraciones.

Editar: Solo tendrá que crear la plantilla de archivo de Excel una vez, solo para familiarizarse con el xml necesario que necesitará generar. Una vez que haya generado el xml, use el siguiente código para enviarlo al usuario:

string fileName = "ExportedFile.xls";
Response.Clear();
Response.Buffer = true;
Response.ContentType = "text/xml";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
ExportToExcel(HttpContext.Current.Response.OutputStream, testUID);
Response.End();



public static void ExportToExcel(Stream outputStream)
{
    XmlTextWriter xmlSink = new XmlTextWriter(outputStream, Encoding.Default);

    //ExcelHeaderString and ExcelStylesString are from the template
    xmlSink.WriteRaw(ExcelHeaderString);
    xmlSink.WriteRaw(ExcelStylesString);

    //write your elements here
    xmlSink.WriteElement("YourElements");

    //ExcelFooterString is from the template
    xmlSink.WriteRaw(ExcelFooterString);
}

Esta biblioteca para .net ha funcionado muy bien en nuestros casos de uso.

  

Esta biblioteca le permite generar libros de Excel utilizando XML, está construido al 100% en C # y no requiere que Excel esté instalado para generar los archivos. Expone un modelo de objeto simple para generar los libros de trabajo XML.

No hay integración integrada con un control GridView, pero escribir un adaptador genérico es bastante fácil y podría reutilizarse en otros proyectos.

Este método va directamente al formato de Excel sin requerir que XML esté instalado en el servidor o mediante el uso de XML.

        Protected Sub ExportToExcel()

        Dim gv1 As GridView = FindControlRecursive(objPlaceHolder, "GridView1")
        If Not gv1 Is Nothing Then
            Response.ClearHeaders()
            Response.ClearContent()

            ' Set the content type to Excel
            Response.ContentType = "application/vnd.ms-excel"

            ' make it open the save as dialog
            Response.AddHeader("content-disposition", "attachment; filename=ExcelExport.xls")

            'Turn off the view state 
            Me.EnableViewState = False

            'Remove the charset from the Content-Type header 
            Response.Charset = String.Empty

            Dim myTextWriter As New System.IO.StringWriter
            Dim myHtmlTextWriter As New System.Web.UI.HtmlTextWriter(myTextWriter)
            Dim frm As HtmlForm = New HtmlForm()
            Controls.Add(frm)
            frm.Controls.Add(gv1)

            'Get the HTML for the control 
            frm.RenderControl(myHtmlTextWriter)

            'Write the HTML to the browser 
            Response.Write(myTextWriter.ToString())
            'End the response 
            Response.End()
        End If
    End Sub

Private Function FindControlRecursive(ByVal root As Control, ByVal id As String) As Control
    If root.ID = id Then
        Return root
    End If
    Dim c As Control
    For Each c In root.Controls
        Dim t As Control = FindControlRecursive(c, id)
        If Not t Is Nothing Then
            Return t
        End If
    Next
    Return Nothing
End Function

Utilicé CarlosAg.ExcelXmlWriter enlace .

Recorrí todas las GridViews HeaderCells y luego todas las filas. Lo único es que si permite la paginación y tiene más de una página, debe configurar el Tamaño de página en un valor alto (yo establezco en 10000000) y luego DataBind the GridView de nuevo y haz tu trabajo. Después, vuelva a establecer el valor de PageSize antiguo. Si alguien sabe una mejor solución, de nada.

EDITAR: El try / catch está ahí porque, por alguna razón, no es posible verificar el tipo de control y luego convertirlo en Label o LinkButton == > control.GetType () .

Aquí está mi código.

 public static Workbook CreateWorkbook(GridView gridView)
    {
        int pageSize = gridView.PageSize;
        gridView.PageSize = 10000000;
        gridView.DataBind();

        Workbook workbook = new Workbook();
        Worksheet sheet = workbook.Worksheets.Add("Export");

        WorksheetStyle style = workbook.Styles.Add("headerStyle");
        style.Font.Bold = true;
        style = workbook.Styles.Add("defaultStyle");
        style.Alignment.WrapText = true;
        style = workbook.Styles.Add("infoStyle");
        style.Font.Color = "Red";
        style.Font.Bold = true;

        sheet.Table.Rows.Add(new WorksheetRow());

        WorksheetRow headerRow = new WorksheetRow();
        foreach (DataControlFieldHeaderCell cell in gridView.HeaderRow.Cells)
        {
            if (!string.IsNullOrEmpty(cell.Text))
                headerRow.Cells.Add(cell.Text, DataType.String, "headerStyle");
            else
                foreach (Control control in cell.Controls)
                {
                    LinkButton linkButton = new LinkButton();
                    try
                    {
                        linkButton = (LinkButton)control;
                    }
                    catch { }

                    if (!string.IsNullOrEmpty(linkButton.Text))
                        headerRow.Cells.Add(linkButton.Text, DataType.String, "headerStyle");
                    else
                    {
                        Label label = new Label();
                        try
                        {
                            label = (Label)control;
                        }
                        catch { }
                        if (!string.IsNullOrEmpty(label.Text))
                            headerRow.Cells.Add(label.Text, DataType.String, "headerStyle");
                    }
                }
        }

        sheet.Table.Rows.Add(headerRow);

        foreach (GridViewRow row in gridView.Rows)
        {
            WorksheetRow wrow = new WorksheetRow();
            foreach (TableCell cell in row.Cells)
            {
                foreach (Control control in cell.Controls)
                {
                    if (control.GetType() == typeof(Label))
                    {
                        wrow.Cells.Add(((Label)control).Text, DataType.String, "defaultStyle");
                    }
                }
            }
            sheet.Table.Rows.Add(wrow);
        }

        gridView.PageSize = pageSize;

        return workbook;
    }
Private exportToExcel As Boolean = False

Private Sub LoadInExcel()
    Me.Response.ClearContent()
    Me.Response.AddHeader("content-disposition", "attachment; filename=MyFile.xls")
    Me.Response.ContentType = "application/ms-excel"
    Dim sw1 As New IO.StringWriter
    Dim htw1 As HtmlTextWriter = New HtmlTextWriter(sw1)
    GridView1.RenderControl(htw1)
    Response.Write(sw1.ToString())
    Response.End()
End Sub

Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
    ' Confirms that an HtmlForm control is rendered for the specified ASP.NET
    ' server control at run time.
End Sub

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    If exportToExcel Then
        LoadInExcel()
    End If

    MyBase.Render(writer)
End Sub

Protected Sub btnPrint_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPrint.Click
    exportToExcel = True
End Sub

Debe tener instalado Excel y hacer referencia a las bibliotecas de interoperabilidad de Office en su proyecto. Añadir:

Importa Microsoft.Office.Core, Importa Microsoft.Office.Interop

La solución anterior toma el gridview y saca el html de él. Luego lo escribe para sobresalir. El html que viene de la cuadrícula incluirá atributos de estilo como el relleno y amp; color. También hará que los encabezados de las columnas se puedan ordenar como enlaces. Cuando utilicé esto, escribí un analizador personalizado para eliminar todo el estilo no deseado y darme solo los datos en bruto. Dejaré esa tarea en tus manos ya que es específica para cada cuadrícula.

Es muy importante que incluya la anulación de VerifyRenderingInServerForm, aunque no haya ningún código dentro de él.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top