Saltar al pie de página
USANDO IRONXL

Cómo exportar GridView a Excel con formato en C#

La exportación de datos de GridView a Excel conservando los colores, las fuentes, los fondos alternos de las filas y los bordes es un requisito que aparece en casi todas las aplicaciones ASP.NET o Windows Forms basadas en datos. El enfoque tradicional —utilizar HtmlTextWriter y StringWriter para representar el control como HTML— genera archivos que muestran advertencias de formato en Excel y fallan de forma silenciosa para los usuarios. IronXL resuelve esto generando archivos XLSX nativos íntegramente en C# sin depender de Microsoft Office, lo que le ofrece un control preciso sobre el estilo de cada celda.

¿Cómo instalas la biblioteca en un proyecto .NET?

Instala IronXL desde NuGet antes de escribir cualquier código de exportación. Abra la Consola del Administrador de Paquetes y ejecute:

Install-Package IronXL
dotnet add package IronXL
Install-Package IronXL
dotnet add package IronXL
SHELL

IronXL es compatible con .NET 8, .NET 9 y .NET 10, así como con .NET Framework 4.6.2 y versiones posteriores. Tras la instalación, añada las siguientes directivas using a cualquier archivo que realice operaciones de Excel:

using IronXL;
using IronXl.Styles;
using IronXL;
using IronXl.Styles;
Imports IronXL
Imports IronXl.Styles
$vbLabelText   $csharpLabel

No se requiere ningún tiempo de ejecución adicional ni interoperabilidad con Office. La biblioteca genera archivos binarios XLSX nativos que se abren correctamente en Microsoft Excel, LibreOffice Calc y Google Sheets.

¿Cómo se exporta un DataGridView de Windows Forms a Excel con formato de celda?

Las aplicaciones de Windows Forms utilizan el control DataGridView en lugar del control basado en web GridView. El patrón de exportación es el mismo en ambos casos: extraer valores de filas y celdas, crear un libro de trabajo IronXL, aplicar estilos y, a continuación, ahorrar o transmitir el resultado.

El enfoque más fiable consiste en convertir la propiedad DataSource del control a un DataTable para evitar iterar las filas visuales, que pueden estar filtradas o paginadas:

using IronXL;
using IronXl.Styles;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;

DataTable dt = (DataTable)dataGridView1.DataSource;

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;

// Header row -- bold, blue background, white text
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    var cell = sheet.GetCellAt(0, col);
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#4472C4");
    cell.Style.Font.Color = "#FFFFFF";
    cell.Style.BottomBorder.Type = BorderType.Thin;
}

// Data rows -- alternating row color
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        string value = dt.Rows[row][col]?.ToString() ?? string.Empty;
        sheet.SetCellValue(row + 1, col, value);

        var cell = sheet.GetCellAt(row + 1, col);
        cell.Style.SetBackgroundColor(row % 2 == 0 ? "#D6DCE5" : "#FFFFFF");
        cell.Style.BottomBorder.Type = BorderType.Thin;
    }
}

// Save via dialog
using var saveDialog = new SaveFileDialog
{
    Filter = "Excel Files|*.xlsx",
    FileName = "GridViewExport.xlsx"
};

if (saveDialog.ShowDialog() == DialogResult.OK)
{
    workBook.SaveAs(saveDialog.FileName);
    MessageBox.Show("Export successful.", "Export",
        MessageBoxButtons.OK, MessageBoxIcon.Information);
}
using IronXL;
using IronXl.Styles;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;

DataTable dt = (DataTable)dataGridView1.DataSource;

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;

// Header row -- bold, blue background, white text
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    var cell = sheet.GetCellAt(0, col);
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#4472C4");
    cell.Style.Font.Color = "#FFFFFF";
    cell.Style.BottomBorder.Type = BorderType.Thin;
}

// Data rows -- alternating row color
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        string value = dt.Rows[row][col]?.ToString() ?? string.Empty;
        sheet.SetCellValue(row + 1, col, value);

        var cell = sheet.GetCellAt(row + 1, col);
        cell.Style.SetBackgroundColor(row % 2 == 0 ? "#D6DCE5" : "#FFFFFF");
        cell.Style.BottomBorder.Type = BorderType.Thin;
    }
}

// Save via dialog
using var saveDialog = new SaveFileDialog
{
    Filter = "Excel Files|*.xlsx",
    FileName = "GridViewExport.xlsx"
};

if (saveDialog.ShowDialog() == DialogResult.OK)
{
    workBook.SaveAs(saveDialog.FileName);
    MessageBox.Show("Export successful.", "Export",
        MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Imports IronXL
Imports IronXl.Styles
Imports System
Imports System.Data
Imports System.IO
Imports System.Windows.Forms

Dim dt As DataTable = DirectCast(dataGridView1.DataSource, DataTable)

Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.DefaultWorkSheet

' Header row -- bold, blue background, white text
For col As Integer = 0 To dt.Columns.Count - 1
    sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
    Dim cell = sheet.GetCellAt(0, col)
    cell.Style.Font.Bold = True
    cell.Style.SetBackgroundColor("#4472C4")
    cell.Style.Font.Color = "#FFFFFF"
    cell.Style.BottomBorder.Type = BorderType.Thin
Next

' Data rows -- alternating row color
For row As Integer = 0 To dt.Rows.Count - 1
    For col As Integer = 0 To dt.Columns.Count - 1
        Dim value As String = If(dt.Rows(row)(col)?.ToString(), String.Empty)
        sheet.SetCellValue(row + 1, col, value)

        Dim cell = sheet.GetCellAt(row + 1, col)
        cell.Style.SetBackgroundColor(If(row Mod 2 = 0, "#D6DCE5", "#FFFFFF"))
        cell.Style.BottomBorder.Type = BorderType.Thin
    Next
Next

' Save via dialog
Using saveDialog As New SaveFileDialog With {
    .Filter = "Excel Files|*.xlsx",
    .FileName = "GridViewExport.xlsx"
}
    If saveDialog.ShowDialog() = DialogResult.OK Then
        workBook.SaveAs(saveDialog.FileName)
        MessageBox.Show("Export successful.", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End If
End Using
$vbLabelText   $csharpLabel

WorkBook.Create inicializa un nuevo libro de trabajo en memoria en formato XLSX. DefaultWorkSheet devuelve la primera hoja, a la que puede cambiar el nombre a través de su propiedad Name antes de guardarla. SetCellValue acepta cadenas, enteros, números de doble precisión y valores DateTime -- IronXL selecciona automáticamente el tipo de celda correcto.

El patrón de colores alternos en las filas -- row % 2 == 0 selecciona #D6DCE5, de lo contrario #FFFFFF -- refleja el estilo de tabla con filas a rayas integrado en Excel. Puedes sustituir cualquier código de color hexadecimal de seis caracteres que se ajuste al sistema de diseño de tu aplicación.

Imágenes de salida

Exportar GridView a Excel con formato C# utilizando IronXL: Imagen 1 - Salida de GridView

Exportar GridView a Excel con formato C# utilizando IronXL: Imagen 2 - Salida en Excel

Exportar GridView a Excel con formato C# utilizando IronXL: Imagen 3 - Salida del mensaje

¿Cómo se exporta un GridView de ASP.NET a Excel y se transmite el archivo al navegador?

Las aplicaciones web requieren un mecanismo de entrega diferente. En lugar de escribir en el sistema de archivos, se serializa el libro de trabajo a un MemoryStream y se escribe en la respuesta HTTP con los encabezados correctos para que el navegador lo trate como una descarga de archivo.

El paso previo importante para las GridViews paginadas: desactivar la paginación (AllowPaging = false) y volver a vincular la fuente de datos antes de exportar, de modo que se capture cada registro, no solo la página actual.

using IronXL;
using IronXl.Styles;
using System;
using System.Data;
using System.IO;
using System.Web.UI;

// Disable paging so all rows are captured
GridView1.AllowPaging = false;
GridView1.DataBind();

DataTable dt = (DataTable)GridView1.DataSource;

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;

// Header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    var cell = sheet.GetCellAt(0, col);
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#2E75B6");
    cell.Style.Font.Color = "#FFFFFF";
    cell.Style.HorizontalAlignment = HorizontalAlignment.Center;
    cell.Style.BottomBorder.Type = BorderType.Medium;
}

// Data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        var cell = sheet.GetCellAt(row + 1, col);
        cell.Style.SetBackgroundColor(row % 2 == 0 ? "#DEEAF1" : "#FFFFFF");
        cell.Style.BottomBorder.Type = BorderType.Thin;
        cell.Style.LeftBorder.Type = BorderType.Thin;
        cell.Style.RightBorder.Type = BorderType.Thin;
    }
}

// Stream to browser
byte[] fileBytes = workBook.ToByteArray();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx");
Response.BinaryWrite(fileBytes);
Response.End();
using IronXL;
using IronXl.Styles;
using System;
using System.Data;
using System.IO;
using System.Web.UI;

// Disable paging so all rows are captured
GridView1.AllowPaging = false;
GridView1.DataBind();

DataTable dt = (DataTable)GridView1.DataSource;

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workBook.DefaultWorkSheet;

// Header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    var cell = sheet.GetCellAt(0, col);
    cell.Style.Font.Bold = true;
    cell.Style.SetBackgroundColor("#2E75B6");
    cell.Style.Font.Color = "#FFFFFF";
    cell.Style.HorizontalAlignment = HorizontalAlignment.Center;
    cell.Style.BottomBorder.Type = BorderType.Medium;
}

// Data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        var cell = sheet.GetCellAt(row + 1, col);
        cell.Style.SetBackgroundColor(row % 2 == 0 ? "#DEEAF1" : "#FFFFFF");
        cell.Style.BottomBorder.Type = BorderType.Thin;
        cell.Style.LeftBorder.Type = BorderType.Thin;
        cell.Style.RightBorder.Type = BorderType.Thin;
    }
}

// Stream to browser
byte[] fileBytes = workBook.ToByteArray();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx");
Response.BinaryWrite(fileBytes);
Response.End();
Imports IronXL
Imports IronXl.Styles
Imports System
Imports System.Data
Imports System.IO
Imports System.Web.UI

' Disable paging so all rows are captured
GridView1.AllowPaging = False
GridView1.DataBind()

Dim dt As DataTable = DirectCast(GridView1.DataSource, DataTable)

Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workBook.DefaultWorkSheet

' Header row
For col As Integer = 0 To dt.Columns.Count - 1
    sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
    Dim cell = sheet.GetCellAt(0, col)
    cell.Style.Font.Bold = True
    cell.Style.SetBackgroundColor("#2E75B6")
    cell.Style.Font.Color = "#FFFFFF"
    cell.Style.HorizontalAlignment = HorizontalAlignment.Center
    cell.Style.BottomBorder.Type = BorderType.Medium
Next

' Data rows
For row As Integer = 0 To dt.Rows.Count - 1
    For col As Integer = 0 To dt.Columns.Count - 1
        sheet.SetCellValue(row + 1, col, If(dt.Rows(row)(col)?.ToString(), String.Empty))
        Dim cell = sheet.GetCellAt(row + 1, col)
        cell.Style.SetBackgroundColor(If(row Mod 2 = 0, "#DEEAF1", "#FFFFFF"))
        cell.Style.BottomBorder.Type = BorderType.Thin
        cell.Style.LeftBorder.Type = BorderType.Thin
        cell.Style.RightBorder.Type = BorderType.Thin
    Next
Next

' Stream to browser
Dim fileBytes As Byte() = workBook.ToByteArray()
Response.Clear()
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("content-disposition", "attachment; filename=GridViewExport.xlsx")
Response.BinaryWrite(fileBytes)
Response.End()
$vbLabelText   $csharpLabel

Response.AddHeader con content-disposition: attachment fuerza la aparición de un cuadro de diálogo de descarga de archivos en todos los navegadores modernos. El tipo MIME application/vnd.openxmlformats-officedocument.spreadsheetml.sheet es el tipo registrado para los archivos XLSX e impide que el navegador intente mostrar el contenido binario en línea.

Para aplicaciones .NET Core, sustituya Response.BinaryWrite por File(fileBytes, contentType, fileName) en una acción del controlador; la lógica de creación del libro de trabajo es idéntica.

¿Cómo se aplica el formato condicional en función de los valores de las celdas?

El formato condicional resalta las celdas que cumplen criterios específicos; por ejemplo, marcando en rojo las fechas vencidas o señalando en naranja los valores por debajo de un umbral. IronXL aplica formato condicional a nivel de celda durante la creación del libro de trabajo:

// Assume "DueDate" is column index 3 and "Amount" is column index 4
DateTime today = DateTime.Today;

for (int row = 0; row < dt.Rows.Count; row++)
{
    // Highlight past-due dates
    if (dt.Columns.Contains("DueDate") && dt.Rows[row]["DueDate"] != DBNull.Value)
    {
        DateTime dueDate = Convert.ToDateTime(dt.Rows[row]["DueDate"]);
        var dueDateCell = sheet.GetCellAt(row + 1, 3);
        if (dueDate < today)
        {
            dueDateCell.Style.SetBackgroundColor("#FF0000");
            dueDateCell.Style.Font.Color = "#FFFFFF";
            dueDateCell.Style.Font.Bold = true;
        }
    }

    // Highlight amounts below threshold
    if (dt.Columns.Contains("Amount") && dt.Rows[row]["Amount"] != DBNull.Value)
    {
        decimal amount = Convert.ToDecimal(dt.Rows[row]["Amount"]);
        var amountCell = sheet.GetCellAt(row + 1, 4);
        if (amount < 100m)
        {
            amountCell.Style.SetBackgroundColor("#FFC000");
        }
    }
}
// Assume "DueDate" is column index 3 and "Amount" is column index 4
DateTime today = DateTime.Today;

for (int row = 0; row < dt.Rows.Count; row++)
{
    // Highlight past-due dates
    if (dt.Columns.Contains("DueDate") && dt.Rows[row]["DueDate"] != DBNull.Value)
    {
        DateTime dueDate = Convert.ToDateTime(dt.Rows[row]["DueDate"]);
        var dueDateCell = sheet.GetCellAt(row + 1, 3);
        if (dueDate < today)
        {
            dueDateCell.Style.SetBackgroundColor("#FF0000");
            dueDateCell.Style.Font.Color = "#FFFFFF";
            dueDateCell.Style.Font.Bold = true;
        }
    }

    // Highlight amounts below threshold
    if (dt.Columns.Contains("Amount") && dt.Rows[row]["Amount"] != DBNull.Value)
    {
        decimal amount = Convert.ToDecimal(dt.Rows[row]["Amount"]);
        var amountCell = sheet.GetCellAt(row + 1, 4);
        if (amount < 100m)
        {
            amountCell.Style.SetBackgroundColor("#FFC000");
        }
    }
}
Imports System

' Assume "DueDate" is column index 3 and "Amount" is column index 4
Dim today As DateTime = DateTime.Today

For row As Integer = 0 To dt.Rows.Count - 1
    ' Highlight past-due dates
    If dt.Columns.Contains("DueDate") AndAlso dt.Rows(row)("DueDate") IsNot DBNull.Value Then
        Dim dueDate As DateTime = Convert.ToDateTime(dt.Rows(row)("DueDate"))
        Dim dueDateCell = sheet.GetCellAt(row + 1, 3)
        If dueDate < today Then
            dueDateCell.Style.SetBackgroundColor("#FF0000")
            dueDateCell.Style.Font.Color = "#FFFFFF"
            dueDateCell.Style.Font.Bold = True
        End If
    End If

    ' Highlight amounts below threshold
    If dt.Columns.Contains("Amount") AndAlso dt.Rows(row)("Amount") IsNot DBNull.Value Then
        Dim amount As Decimal = Convert.ToDecimal(dt.Rows(row)("Amount"))
        Dim amountCell = sheet.GetCellAt(row + 1, 4)
        If amount < 100D Then
            amountCell.Style.SetBackgroundColor("#FFC000")
        End If
    End If
Next row
$vbLabelText   $csharpLabel

Este patrón es modulable: añada tantas comprobaciones condicionales como requieran sus necesidades de generación de informes. Dado que IronXL opera celda por celda, puede combinar el formato condicional con la lógica de alternancia de colores de filas aplicando el estilo condicional después del estilo de fila base.

¿Cómo se ajusta el ancho de las columnas y se fija la fila de encabezado?

Una exportación a Excel con formato Professional incluye anchos de columna adecuados y una fila de encabezado fija, de modo que los nombres de las columnas permanezcan visibles cuando los usuarios se desplacen por conjuntos de datos de gran tamaño.

IronXL expone el ancho de columna a través del accesor de columna WorkSheet y la fijación de encabezados a través del método FreezeRows:

// Auto-size columns 0 through the last column index
for (int col = 0; col < dt.Columns.Count; col++)
{
    // Set column width in character units (1 unit ≈ one default character width)
    sheet.SetColumnWidth(col, 20);
}

// Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1);

// Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20);
// Auto-size columns 0 through the last column index
for (int col = 0; col < dt.Columns.Count; col++)
{
    // Set column width in character units (1 unit ≈ one default character width)
    sheet.SetColumnWidth(col, 20);
}

// Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1);

// Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20);
' Auto-size columns 0 through the last column index
For col As Integer = 0 To dt.Columns.Count - 1
    ' Set column width in character units (1 unit ≈ one default character width)
    sheet.SetColumnWidth(col, 20)
Next

' Freeze the first row (index 0) so the header stays visible while scrolling
sheet.FreezeRows(1)

' Optionally set row height for the header (in points)
sheet.SetRowHeight(0, 20)
$vbLabelText   $csharpLabel

Para uso en producción, considere calcular el ancho basándose en el número máximo de caracteres de cada columna en lugar de utilizar un valor fijo. Iterar los valores de la columna DataTable, medir la longitud de la cadena y multiplicarla por un factor de ancho de carácter adecuado para el tamaño de fuente elegido.

También puede aplicar un color de fondo a las celdas de Excel utilizando C# independientemente de la lógica de bandas de filas para lograr un estilo más detallado.

¿Cómo se exporta una DataTable a Excel sin un control GridView?

Muchas aplicaciones .NET rellenan datos mediante llamadas a servicios o consultas a bases de datos y los almacenan en un DataTable sin vincularlos nunca a un control de la interfaz de usuario. Puedes exportar un DataTable directamente a Excel sin necesidad de instanciar un GridView.

Esta es la ruta más eficiente para tareas en segundo plano, informes programados y puntos finales de API que necesitan generar archivos Excel en el servidor:

using IronXL;
using IronXl.Styles;
using System.Data;

public static byte[] DataTableToExcelBytes(DataTable dt, string sheetName = "Report")
{
    WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet sheet = workBook.CreateWorkSheet(sheetName);

    // Header
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
        var cell = sheet.GetCellAt(0, col);
        cell.Style.Font.Bold = true;
        cell.Style.SetBackgroundColor("#4472C4");
        cell.Style.Font.Color = "#FFFFFF";
    }

    // Data
    for (int row = 0; row < dt.Rows.Count; row++)
    {
        for (int col = 0; col < dt.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        }
    }

    return workBook.ToByteArray();
}
using IronXL;
using IronXl.Styles;
using System.Data;

public static byte[] DataTableToExcelBytes(DataTable dt, string sheetName = "Report")
{
    WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet sheet = workBook.CreateWorkSheet(sheetName);

    // Header
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
        var cell = sheet.GetCellAt(0, col);
        cell.Style.Font.Bold = true;
        cell.Style.SetBackgroundColor("#4472C4");
        cell.Style.Font.Color = "#FFFFFF";
    }

    // Data
    for (int row = 0; row < dt.Rows.Count; row++)
    {
        for (int col = 0; col < dt.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        }
    }

    return workBook.ToByteArray();
}
Imports IronXL
Imports IronXl.Styles
Imports System.Data

Public Shared Function DataTableToExcelBytes(dt As DataTable, Optional sheetName As String = "Report") As Byte()
    Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
    Dim sheet As WorkSheet = workBook.CreateWorkSheet(sheetName)

    ' Header
    For col As Integer = 0 To dt.Columns.Count - 1
        sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
        Dim cell = sheet.GetCellAt(0, col)
        cell.Style.Font.Bold = True
        cell.Style.SetBackgroundColor("#4472C4")
        cell.Style.Font.Color = "#FFFFFF"
    Next

    ' Data
    For row As Integer = 0 To dt.Rows.Count - 1
        For col As Integer = 0 To dt.Columns.Count - 1
            sheet.SetCellValue(row + 1, col, If(dt.Rows(row)(col)?.ToString(), String.Empty))
        Next
    Next

    Return workBook.ToByteArray()
End Function
$vbLabelText   $csharpLabel

Este método devuelve un byte[] que puede escribir en el disco, transmitir desde un punto final de API, adjuntar a un correo electrónico o almacenar en caché en la memoria. Para técnicas relacionadas, consulte la guía sobre cómo exportar una DataTable a Excel y el tutorial sobre la forma más rápida de exportar una DataTable a Excel.

¿Cómo gestionas los grandes conjuntos de datos y el rendimiento?

La exportación de decenas de miles de filas a Excel exige prestar atención a la asignación de memoria. Crear un nuevo objeto de estilo de celda para cada celda de una cuadrícula grande es el cuello de botella de rendimiento más común. Reutilice las definiciones de estilo siempre que sea posible, aplicando estilos a rangos de celdas en lugar de a celdas individuales:

Enfoques de exportación de IronXL según el tamaño del conjunto de datos
Tamaño del conjunto de datos Enfoque recomendado Consideración clave
Hasta 5000 filas Bucle de estilo celda por celda Código sencillo, sobrecarga insignificante
5 000 - 50 000 filas Aplicación de estilo a nivel de rango Reduce significativamente las asignaciones de objetos
Más de 50 000 filas Exportación directa de DataTable, estilo minimalista Minimizar las operaciones por celda; utilizar streaming si está disponible

Para GridViews paginadas, establezca siempre AllowPaging = false y vuelva a vincular antes de exportar. La paginación limita el número de filas visibles en el control, por lo que una exportación paginada captura solo la página actual en lugar de todo el conjunto de datos, lo que suele ser una fuente frecuente de errores de exportación incompleta.

También puede consultar la guía sobre cómo exportar una lista de objetos a Excel en C# para ver patrones que funcionan con colecciones fuertemente tipadas en lugar de filas sin tipar DataTable.

¿Cómo se exporta un GridView en ASP.NET Core o Blazor?

Las aplicaciones ASP.NET Core y Blazor no disponen de un control Web Forms GridView, pero el reto subyacente de la exportación de datos es el mismo: tomar una colección de objetos o un DataTable, crear un libro de trabajo con estilo y generar un archivo. El código de creación del libro de trabajo es idéntico; solo cambia el mecanismo de entrega.

En una aplicación Blazor, activa la descarga de un archivo mediante la interoperabilidad de JavaScript:

// In a Blazor component or service
using IronXL;
using System.Data;
using Microsoft.JSInterop;

public async Task ExportToExcelAsync(DataTable dt, IJSRuntime js)
{
    WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet sheet = workBook.DefaultWorkSheet;

    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
        var cell = sheet.GetCellAt(0, col);
        cell.Style.Font.Bold = true;
        cell.Style.SetBackgroundColor("#4472C4");
        cell.Style.Font.Color = "#FFFFFF";
    }

    for (int row = 0; row < dt.Rows.Count; row++)
    {
        for (int col = 0; col < dt.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        }
    }

    byte[] fileBytes = workBook.ToByteArray();
    string base64 = Convert.ToBase64String(fileBytes);
    await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
// In a Blazor component or service
using IronXL;
using System.Data;
using Microsoft.JSInterop;

public async Task ExportToExcelAsync(DataTable dt, IJSRuntime js)
{
    WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet sheet = workBook.DefaultWorkSheet;

    for (int col = 0; col < dt.Columns.Count; col++)
    {
        sheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
        var cell = sheet.GetCellAt(0, col);
        cell.Style.Font.Bold = true;
        cell.Style.SetBackgroundColor("#4472C4");
        cell.Style.Font.Color = "#FFFFFF";
    }

    for (int row = 0; row < dt.Rows.Count; row++)
    {
        for (int col = 0; col < dt.Columns.Count; col++)
        {
            sheet.SetCellValue(row + 1, col, dt.Rows[row][col]?.ToString() ?? string.Empty);
        }
    }

    byte[] fileBytes = workBook.ToByteArray();
    string base64 = Convert.ToBase64String(fileBytes);
    await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
Imports IronXL
Imports System.Data
Imports Microsoft.JSInterop

Public Async Function ExportToExcelAsync(dt As DataTable, js As IJSRuntime) As Task
    Dim workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
    Dim sheet As WorkSheet = workBook.DefaultWorkSheet

    For col As Integer = 0 To dt.Columns.Count - 1
        sheet.SetCellValue(0, col, dt.Columns(col).ColumnName)
        Dim cell = sheet.GetCellAt(0, col)
        cell.Style.Font.Bold = True
        cell.Style.SetBackgroundColor("#4472C4")
        cell.Style.Font.Color = "#FFFFFF"
    Next

    For row As Integer = 0 To dt.Rows.Count - 1
        For col As Integer = 0 To dt.Columns.Count - 1
            sheet.SetCellValue(row + 1, col, If(dt.Rows(row)(col)?.ToString(), String.Empty))
        Next
    Next

    Dim fileBytes As Byte() = workBook.ToByteArray()
    Dim base64 As String = Convert.ToBase64String(fileBytes)
    Await js.InvokeVoidAsync("downloadFileFromBase64", base64, "GridViewExport.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
End Function
$vbLabelText   $csharpLabel

La guía completa del patrón de descarga de Blazor se encuentra en el tutorial de exportación de Blazor a Excel. Para un enfoque basado en controladores de ASP.NET Core, consulte el tutorial de exportación a Excel de .NET Core.

Estilo de fuente y opciones de borde

IronXL ofrece controles detallados de fuente y borde a través del objeto Style en cada celda. La gama completa de estilos de fuente de Excel en C# incluye negrita, cursiva, subrayado, tamaño y color. Los tipos de borde disponibles a través de BorderType incluyen fino, medio, grueso, discontinuo, punteado, doble y varias variantes de línea muy fina.

Para las filas de encabezado o los pies de página de resumen combinados, IronXL también admite la fusión de celdas en Excel mediante C#, lo cual resulta útil cuando se desea que una única celda de título abarque varias columnas por encima de la tabla de datos.

Para ajustar automáticamente el ancho de las columnas tras rellenarlas con datos, consulte la guía "Ajustar automáticamente el ancho de las celdas en Excel con C#" para conocer el método recomendado.

¿Por qué una biblioteca nativa de Excel genera exportaciones más limpias que HtmlTextWriter?

La técnica tradicional de exportación de ASP.NET —sobrescribir VerifyRenderingInServerForm, crear un StringWriter y un HtmlTextWriter, y escribir el control renderizado en la respuesta— genera un documento HTML con la extensión .xls. Microsoft Excel abre estos archivos con una advertencia de compatibilidad porque el archivo no está realmente en formato binario de Excel ni en formato OOXML. Los estilos se limitan al CSS en línea que Excel interpreta parcialmente. No es posible aplicar formato condicional. Los usuarios de plataformas que no sean Windows o que utilicen LibreOffice observan un resultado de menor calidad.

IronXL escribe directamente en el formato Open XML Spreadsheet (OOXML). El resultado es un archivo .xlsx válido —idéntico al que crea el propio Excel— que se abre sin advertencias en Excel, LibreOffice, Google Sheets y Numbers en macOS. El formato se codifica como estilos de hoja de cálculo, no como atributos HTML, por lo que se conserva en las idas y venidas y en la visualización multiplataforma.

Comparación de métodos de exportación para ASP.NET GridView
Método Formato de archivo Advertencias de formato Compatibilidad total con el estilo Se requiere oficina
HtmlTextWriter + StringWriter HTML camuflado como XLS No No
Office Interop (COM) Nativo XLS/XLSX No
IronXL Nativo XLSX/XLS No No

La documentación oficial de Microsoft sobre el SDK de Open XML explica el formato subyacente que genera IronXL. La especificación OOXML, mantenida por ECMA International, define el estándar que garantiza la compatibilidad entre aplicaciones. La documentación del control GridView de ASP.NET en Microsoft Docs describe el modelo de control del que se nutren los patrones de exportación mencionados anteriormente.

¿Cuales son tus próximos pasos?

Ahora dispone de los patrones necesarios para exportar datos de GridView y DataGridView a archivos XLSX con el formato adecuado utilizando IronXL, lo que abarca los modelos de entrega de Windows Forms, ASP.NET Web Forms, ASP.NET Core y Blazor.

Para ir más allá:

Preguntas Frecuentes

¿Cómo puedo exportar datos de GridView a Excel en C#?

Puede exportar datos de GridView a Excel en C# con la biblioteca IronXL. Esta biblioteca le permite crear archivos de Excel mediante programación y exportar datos fácilmente, incluyendo formato y estilos.

¿Por qué debería utilizar IronXL para exportar datos de GridView?

IronXL simplifica el proceso de exportación de datos de GridView con su API intuitiva, lo que le permite mantener el formato y aplicar estilos sin esfuerzo, lo que puede ser un desafío con los métodos tradicionales.

¿IronXL admite el formato al exportar GridView a Excel?

Sí, IronXL admite varias opciones de formato, incluidas fuentes, colores y estilos de celda, lo que garantiza que los archivos de Excel exportados tengan un aspecto profesional y mantengan el diseño previsto.

¿Puedo personalizar la apariencia de los archivos Excel generados a partir de datos de GridView?

IronXL ofrece una variedad de opciones de personalización para archivos de Excel, lo que le permite ajustar estilos de celda, fuentes, colores y más para que coincidan con sus requisitos específicos al exportar desde GridView.

¿Es posible exportar grandes conjuntos de datos de GridView a Excel usando IronXL?

IronXL es capaz de manejar grandes conjuntos de datos de manera eficiente, lo que garantiza que pueda exportar datos extensos de GridView a Excel sin problemas de rendimiento.

¿Cuáles son los beneficios de exportar datos de GridView a Excel usando IronXL sobre otros métodos?

IronXL ofrece un enfoque más optimizado y flexible para exportar datos de GridView, proporcionando un soporte sólido para el formato, la personalización y el manejo de grandes conjuntos de datos, lo que lo hace superior a muchos otros métodos.

¿Cómo mantengo la integridad de los datos al exportar GridView a Excel?

IronXL garantiza la integridad de los datos al convertir y preservar con precisión los tipos y formatos de datos durante el proceso de exportación de GridView a Excel.

¿Puede IronXL exportar datos de controles GridView con estructuras complejas?

Sí, IronXL puede manejar y exportar eficazmente datos desde controles GridView con estructuras complejas, manteniendo la jerarquía y el formato en el archivo Excel resultante.

¿A qué formatos de archivos puede IronXL exportar datos de GridView?

IronXL exporta datos principalmente a formatos de Excel como XLSX, pero también admite otros formatos como CSV, lo que permite flexibilidad según sus necesidades.

¿Existe soporte para exportar GridView con formato condicional usando IronXL?

IronXL admite el formato condicional, lo que le permite establecer reglas y estilos que se ajustan dinámicamente en función de los valores de las celdas al exportar datos de GridView a Excel.

Jordi Bardia
Ingeniero de Software
Jordi es más competente en Python, C# y C++. Cuando no está aprovechando sus habilidades en Iron Software, está programando juegos. Compartiendo responsabilidades para pruebas de productos, desarrollo de productos e investigación, Jordi agrega un valor inmenso a la mejora continua del producto. La experiencia variada lo mantiene ...
Leer más

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame