Mostrar una hoja de cálculo de Excel en una página web dinámica aspx usando un rango de celdas como origen de datos de un DataGrid, en C# y en VB
ADO .NET proporciona métodos para conectar con diferentes almacenes de datos. En este ejercicio se utilizan clases pertenecientes a los espacios de nombres System.Data y System.Data.OleDb para conectar con una hoja de cálculo de Microsoft Excel. Un grupo de celdas de la hoja de cálculo, englobadas en un rango con nombre, hace la función de tabla del DataSet que es mostrada en el DataGrid.
Hoja de cálculo de Excel
- creamos la hoja de cálculo en Microsoft Excel
- hay que asignar un nombre a un grupo o rango de celdas, primero seleccionamos las celdas (filas y columnas) con los datos que deseamos transferir a la página aspx
- con las celdas seleccionadas, para crear el rango de celdas en Excel 2003 y versiones anteriores tenemos que ir al menú Insertar / Nombre / Definir
- en Excel 2007 tenemos que ir al menú Fórmulas / Asignar nombre a un rango
- en Excel 2013 – 2019 tenemos que ir al menú Fórmulas / Asignar nombre
- damos un nombre al rango seleccionado y pulsamos Aceptar (este nombre es el que vamos a emplear como nombre de tabla en la sentencia SQL de selección que rellenará un DataSet desde un OleDbDataAdapter)
- guardamos la hoja de Excel (en este ejercicio es el archivo que se llama exceldata.xls).
ASP .NET
Creamos el proyecto en Visual Studio. La página dinámica aspx contiene 2 objetos DataGrid (de nombre rejilla). En la página de código conectamos con la hoja de Excel usando una cadena de conexión de tipo OleDb. Se usa el proveedor OLEDB de Microsoft Jet que es un motor de bases de datos utilizado por Windows desde el año 1992 compatible con los programas de Office y con .NET aunque, para tareas profesionales, fue reemplazado por MSDE (Microsoft Desktop Engine) y más recientemente por SQL Server Express.
En este ejemplo el archivo de Excel, llamado exceldata.xls, contiene una serie de cifras que constituyen la altimetría de un puerto de montaña (Sierra Nevada) y el nombre del rango de celdas es sierra para la altimetría kilómetro a kilómetro y sierratotal para los números totales de pendiente, distancia y coeficiente. Los DataGrid se pueden formatear en la página aspx cambiando su aspecto (colores, fuentes, etc.) y, si contienen un número elevado de filas, se puede paginar (en este ejemplo he configurado rejilla en 3 páginas de 15 filas cada una). El libro de Excel puede contener más de una hoja y ya ves que es posible enlazar varios DataGrid con varios nombres de rangos diferentes.
VB
Private datos1, datos2 As DataSet
Private adaptador1, adaptador2 As OleDbDataAdapter
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'SmartNavigation establece un valor que indica si los desplazamientos inteligentes
'están habilitados. Es true si están habilitados; de lo contrario, es false.
'Se puede establecer el atributo SmartNavigation:
'- en la directiva @ Page del archivo.aspx
'-.en el código Visual Basic .NET
'Actualmente SmartNavigation se considera código válido aunque obsoleto
'puede ser reemplazado por MaintainScrollPositionOnPostBack
'Me.SmartNavigation = True
Me.Page.MaintainScrollPositionOnPostBack = True
Try
' cadena de conexión específica para el proveedor
' para usar BD de Access con extensión accdb (también sirve para .mdb) hay que recurrir a Provider=Microsoft.ACE.OLEDB.12.0
Dim cadenaCon As String = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & Server.MapPath("exceldata.xls") & ";" & "Extended Properties=Excel 8.0;"
' para usar BD de Access con extensión mdb más antigua hay que recurrir a Provider=Microsoft.Jet.OLEDB.4.0
'Dim cadenaCon As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("exceldata.xls") & ";" & "Extended Properties=Excel 8.0;"
' OleDbConnection a la que se le pasa la cadena de conexión
Dim con As OleDbConnection = New OleDbConnection(cadenaCon)
' abrir la conexión con el origen de datos
con.Open()
' OleDbDataAdapter creado con la sentencia SQL y el nombre del objeto OleDbConnection
adaptador1 = New OleDbDataAdapter("SELECT * FROM sierra", con)
' DataSet para ser rellenado desde el OleDbDataAdapter
datos1 = New DataSet
adaptador1.Fill(datos1, "XLData")
' DataGrid con origen en el DataSet
rejilla1.DataSource = datos1.Tables(0)
rejilla1.DataBind()
' OleDbDataAdapter creado con la sentencia SQL y el nombre del objeto OleDbConnection
adaptador2 = New OleDbDataAdapter("SELECT * FROM sierratotal", con)
' DataSet para ser rellenado desde el OleDbDataAdapter
datos2 = New DataSet
adaptador2.Fill(datos2, "XLData")
' DataGrid con origen en el DataSet
rejilla2.DataSource = datos2.Tables(0)
rejilla2.DataBind()
'generar texto en la página, antes de las tablas con los datos
Response.Write("<br />")
Response.Write("<DIV ALIGN=""center""><FONT SIZE=""4""><B>Leer una hoja de Excel desde ASP .NET" &
"</B></FONT><br /><br /><FONT SIZE=""2""><STRONG>Altimetría de Sierra Nevada</STRONG></FONT><br />")
LbInfo.Text = "<DIV ALIGN=""center""><FONT SIZE=""2"">Número de filas por página: " + "<B>" + rejilla1.PageSize.ToString + "</B><BR/><BR/>
Ruta al archivo de Excel: <I>" + Server.MapPath("exceldata.xls") + "</I></FONT></DIV>"
' cerrar la conexión con el origen de datos
con.Close()
Catch pollo As Exception
Response.Write("<br /><br /><br /><TABLE ALIGN=""CENTER"" WIDTH=""500""><TR><TD>" & _
"<FONT FACE=""VERDANA"" SIZE=""3"" COLOR=""RED""><B>ERROR</B>: " & _
pollo.Message & "</FONT></TD></TR></TABLE>")
End Try
End Sub
C#
private DataSet datos1;
private DataSet datos2;
private OleDbDataAdapter adaptador1;
private OleDbDataAdapter adaptador2;
private void Page_Load(System.Object sender, System.EventArgs e)
{
//SmartNavigation establece un valor que indica si los desplazamientos inteligentes
//están habilitados. Es true si están habilitados; de lo contrario, es false.
//Se puede establecer el atributo SmartNavigation:
//- en la directiva @ Page del archivo.aspx
//-.en el código Visual Basic .NET
//Actualmente SmartNavigation se considera código válido aunque obsoleto
//puede ser reemplazado por MaintainScrollPositionOnPostBack
//Me.SmartNavigation = True
this.Page.MaintainScrollPositionOnPostBack = true;
try
{
// cadena de conexión específica para el proveedor
// para usar BD de Access con extensión accdb (también sirve para .mdb) hay que recurrir a Provider=Microsoft.ACE.OLEDB.12.0
string cadenaCon = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" + Server.MapPath("exceldata.xls") + ";" + "Extended Properties=Excel 8.0;";
// para usar BD de Access con extensión mdb más antigua hay que recurrir a Provider=Microsoft.Jet.OLEDB.4.0
//Dim cadenaCon As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("exceldata.xls") & ";" & "Extended Properties=Excel 8.0;"
// OleDbConnection a la que se le pasa la cadena de conexión
OleDbConnection con = new OleDbConnection(cadenaCon);
// abrir la conexión con el origen de datos
con.Open();
// OleDbDataAdapter creado con la sentencia SQL y el nombre del objeto OleDbConnection
adaptador1 = new OleDbDataAdapter("SELECT * FROM sierra", con);
// DataSet para ser rellenado desde el OleDbDataAdapter
datos1 = new DataSet();
adaptador1.Fill(datos1, "XLData");
// DataGrid con origen en el DataSet
rejilla1.DataSource = datos1.Tables[0];
rejilla1.DataBind();
// OleDbDataAdapter creado con la sentencia SQL y el nombre del objeto OleDbConnection
adaptador2 = new OleDbDataAdapter("SELECT * FROM sierratotal", con);
// DataSet para ser rellenado desde el OleDbDataAdapter
datos2 = new DataSet();
adaptador2.Fill(datos2, "XLData");
// DataGrid con origen en el DataSet
rejilla2.DataSource = datos2.Tables[0];
rejilla2.DataBind();
//generar texto en la página, antes de las tablas con los datos
Response.Write("<br />");
Response.Write("<DIV ALIGN=\"center\"><FONT SIZE=\"4\"><B>Leer una hoja de Excel desde ASP .NET" +
"</B></FONT><br /><br /><FONT SIZE=\"2\"><STRONG>Altimetría de Sierra Nevada</STRONG></FONT><br />");
LbInfo.Text = "<DIV ALIGN=\"center\"><FONT SIZE=\"2\">Número de filas por página: <B>" + rejilla1.PageSize.ToString() + "</B></FONT></DIV><BR/><BR/>";
LbRuta.Text = "<DIV ALIGN=\"center\"><FONT SIZE=\"2\">Ruta al archivo de Excel: " + Server.MapPath("exceldata.xls") + "</FONT></DIV>";
// cerrar la conexión con el origen de datos
con.Close();
}
catch (Exception pollo)
{
Response.Write("<br /><br /><br /><TABLE ALIGN=\"CENTER\" WIDTH=\"500\"><TR><TD>" +
"<FONT FACE=\"VERDANA\" SIZE=\"3\" COLOR=\"RED\"><B>ERROR</B>: " +
pollo.Message + "</FONT></TD></TR></TABLE>");
}
}
Al cambiar de página en el DataGrid se llama al método IndexChanged:
VB
Sub Rejilla_IndexChanged(ByVal obj As Object, ByVal e As DataGridPageChangedEventArgs)
rejilla1.CurrentPageIndex = e.NewPageIndex
rejilla1.DataBind()
End Sub
C#
public void Rejilla_IndexChanged(object obj, DataGridPageChangedEventArgs e)
{
rejilla1.CurrentPageIndex = e.NewPageIndex;
rejilla1.DataBind();
}

Puedes descargar archivos ZIP con las aplicaciones en Visual Studio 2022: VB C# .

Muy bueno, se puede hacer si el rango de Excel es variable en tamaño, o sea si cambian las cantidades de filas o columnas o ambas? Gracias por el contenido.
Pero pon un nombre en el campo nombre, el que sea, no lo dejes en blanco.
Hace más de 2 años que estoy fuera de Windows y por extension de Excel, usando Mac. Realmente no sé la respuesta, ya ves que mi ejercicio usa un rango de celdas fijo por lo que no sirve para lo que quieres.
Copilot me da esta ayuda, la copio tal cual por si es útil para ti.
En ASP .NET, puedes crear un rango de celdas de Excel variable usando el objeto Range y asignándolo a una variable con la instrucción Set. Para esto, define el rango dinámicamente usando propiedades como Cells (por número de fila y columna) o calculando las celdas de inicio y fin.
' Declarar una variable de tipo Range
Dim miRango As Range
' Crear un rango variable basado en variables (por ejemplo, fila_inicio, columna_inicio, etc.)
' En este ejemplo, las variables fila_inicio y columna_inicio se han definido previamente.
Set miRango = Worksheets("Hoja1").Range(Cells(fila_inicio, columna_inicio), Cells(fila_fin, columna_fin))
' Ahora puedes trabajar con este rango variable
miRango.Value = "Valor de prueba"
miRango.Font.Bold = True
—–
// En C# se usaría una librería como EPPlus
using OfficeOpenXml;
using OfficeOpenXml.Style;
// Crear un objeto ExcelPackage y una hoja de trabajo
var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Hoja1");
// Definir las variables para el rango
int fila_inicio = 2;
int columna_inicio = 3;
int fila_fin = 5;
int columna_fin = 6;
// Obtener el rango de celdas de forma dinámica
// La sintaxis de EPPlus es ligeramente diferente
var miRango = worksheet.Cells[fila_inicio, columna_inicio, fila_fin, columna_fin];
// Trabajar con el rango
miRango.Value = "Valor de prueba";
miRango.Style.Font.Bold = true;
—–
// Con Microsoft Office Interop
using Microsoft.Office.Interop.Excel;
// Crear una aplicación de Excel y una hoja de trabajo
var excelApp = new Application();
var workbook = excelApp.Workbooks.Add();
var worksheet = (Worksheets)workbook.Sheets;
// Declarar las variables
int fila_inicio = 2;
int columna_inicio = 3;
int fila_fin = 5;
int columna_fin = 6;
// Obtener el rango usando las variables
var miRango = worksheet.get_Range(worksheet.Cells[fila_inicio, columna_inicio], worksheet.Cells[fila_fin, columna_fin]);
// Trabajar con el rango
miRango.Value = "Valor de prueba";
miRango.Font.Bold = true;
// Guardar y cerrar el libro de trabajo
workbook.SaveAs("Ejemplo.xlsx");
workbook.Close();
excelApp.Quit();