Importar hojas de cálculo de Excel en Python es una tarea habitual en análisis de datos, automatización administrativa y creación de informes. Con Pandas puedes leer archivos .xlsx, seleccionar hojas y columnas, corregir tipos, tratar valores vacíos y exportar el resultado sin recorrer cada celda manualmente. La clave no es solo conseguir que el archivo se abra, sino construir un proceso reproducible que valide lo recibido antes de utilizarlo.
Antes de comenzar conviene revisar la guía de Pandas para principiantes, el tutorial de análisis de datos con Pandas y NumPy, el trabajo con archivos CSV, el manejo de excepciones y la lectura de archivos de texto.
Las referencias externas principales son la documentación oficial de pandas.read_excel y la documentación oficial de openpyxl, el motor utilizado habitualmente para archivos modernos de Excel.
Instalar las dependencias
python -m pip install pandas openpyxl
Usar python -m pip reduce el riesgo de instalar paquetes en un intérprete diferente. Trabaja dentro de un entorno virtual y registra las versiones en un archivo de dependencias cuando el script vaya a ejecutarse en otro equipo.
Leer la primera hoja
import pandas as pd
df = pd.read_excel("ventas.xlsx")
print(df.head())
print(df.info())
head() permite inspeccionar las primeras filas, mientras que info() muestra columnas, tipos y cantidad de valores no nulos. Esta revisión inicial es importante porque Excel puede mezclar números, texto y fechas en una misma columna.
Seleccionar una hoja concreta
df = pd.read_excel(
"ventas.xlsx",
sheet_name="Enero",
)
Si no conoces los nombres disponibles, abre el libro con ExcelFile:
archivo = pd.ExcelFile("ventas.xlsx")
print(archivo.sheet_names)
df = pd.read_excel(archivo, sheet_name=archivo.sheet_names[0])
Para cargar varias hojas de una vez utiliza una lista o sheet_name=None. El resultado será un diccionario cuyas claves son los nombres de las hojas.
Leer solo las columnas necesarias
df = pd.read_excel(
"ventas.xlsx",
usecols=["Fecha", "Producto", "Cantidad", "Precio"],
)
Limitar columnas disminuye memoria y simplifica la validación. También puedes usar posiciones, por ejemplo usecols="A:D", aunque los nombres suelen resistir mejor los cambios de orden.
Omitir filas de títulos o notas
df = pd.read_excel(
"ventas.xlsx",
skiprows=2,
header=0,
)
Muchas hojas creadas para personas incluyen un título grande, logotipos o notas antes de la tabla. Ajusta skiprows y confirma que los nombres obtenidos son los esperados. Nunca asumas que el encabezado está siempre en la primera fila.
Normalizar nombres de columnas
df.columns = (
df.columns
.astype(str)
.str.strip()
.str.lower()
.str.replace(" ", "_", regex=False)
)
Después puedes validar el esquema:
requeridas = {"fecha", "producto", "cantidad", "precio"}
faltantes = requeridas - set(df.columns)
if faltantes:
raise ValueError(f"Faltan columnas: {sorted(faltantes)}")
Esta comprobación evita que el proceso continúe con datos incompletos y genere resultados engañosos.
Convertir fechas correctamente
df["fecha"] = pd.to_datetime(
df["fecha"],
errors="coerce",
dayfirst=True,
)
errors="coerce" convierte valores inválidos en NaT. Después debes decidir si descartarlos, corregirlos o detener el proceso:
fechas_invalidas = df["fecha"].isna().sum()
if fechas_invalidas:
print(f"Fechas inválidas: {fechas_invalidas}")
Convertir números con símbolos y separadores
Una columna de precio puede contener símbolos, espacios o comas:
texto = (
df["precio"]
.astype(str)
.str.replace("€", "", regex=False)
.str.replace(" ", "", regex=False)
.str.replace(",", ".", regex=False)
)
df["precio"] = pd.to_numeric(texto, errors="coerce")
No sustituyas comas a ciegas si el archivo mezcla separadores de miles y decimales. Define una regla según el origen de los datos y documenta el formato esperado.
Tratar valores ausentes
df["cantidad"] = pd.to_numeric(df["cantidad"], errors="coerce")
df["cantidad"] = df["cantidad"].fillna(0)
df["producto"] = df["producto"].fillna("Sin identificar")
Rellenar con cero no siempre es correcto. Un dato desconocido puede ser diferente de una venta con cantidad cero. La decisión debe responder a una regla del negocio, no únicamente a la comodidad del código.
Eliminar filas completamente vacías
df = df.dropna(how="all")
Para eliminar registros incompletos solo en campos críticos:
df = df.dropna(subset=["fecha", "producto", "precio"])
Leer todas las hojas y combinarlas
hojas = pd.read_excel("ventas.xlsx", sheet_name=None)
partes = []
for nombre, datos in hojas.items():
datos = datos.copy()
datos["hoja_origen"] = nombre
partes.append(datos)
ventas = pd.concat(partes, ignore_index=True)
Conservar la hoja de origen facilita investigar errores y comparar departamentos o meses. Antes de concatenar, verifica que todas las hojas utilicen las mismas columnas.
Manejar archivos grandes
Excel no está diseñado para transmisión por bloques como CSV. Si el libro es enorme, limita hojas y columnas, evita fórmulas innecesarias y considera convertirlo a CSV o Parquet para procesos repetidos. También puedes leer el archivo una vez, limpiar los datos y guardar un formato más eficiente.
Capturar errores relevantes
from pathlib import Path
import pandas as pd
ruta = Path("ventas.xlsx")
try:
if not ruta.is_file():
raise FileNotFoundError(ruta)
df = pd.read_excel(ruta, engine="openpyxl")
except FileNotFoundError:
print("El archivo no existe")
except PermissionError:
print("Cierra Excel o revisa los permisos")
except ValueError as error:
print(f"El libro no tiene el formato esperado: {error}")
except Exception as error:
print(f"No fue posible leer el archivo: {error}")
En producción, registra el traceback con logging. Evita un except vacío, porque ocultaría archivos dañados o errores de configuración.
Exportar el resultado limpio
df.to_excel(
"ventas_limpias.xlsx",
index=False,
sheet_name="Datos",
)
También puedes exportar a CSV:
df.to_csv(
"ventas_limpias.csv",
index=False,
encoding="utf-8",
)
Crear una función reutilizable
def cargar_ventas(ruta):
df = pd.read_excel(
ruta,
usecols=["Fecha", "Producto", "Cantidad", "Precio"],
engine="openpyxl",
)
df.columns = [c.strip().lower() for c in df.columns]
df["fecha"] = pd.to_datetime(df["fecha"], errors="coerce")
df["cantidad"] = pd.to_numeric(df["cantidad"], errors="coerce")
df["precio"] = pd.to_numeric(df["precio"], errors="coerce")
return df.dropna(subset=["fecha", "producto", "precio"])
Una función clara facilita probar archivos correctos, columnas faltantes, fechas inválidas y libros vacíos. Para procesos críticos, crea pruebas con pequeños archivos de ejemplo y no dependas de una hoja real modificada manualmente.
Errores frecuentes
Los fallos más comunes son olvidar instalar openpyxl, utilizar un nombre de hoja incorrecto, confiar en tipos detectados automáticamente, ignorar espacios en encabezados, mezclar fechas regionales y sobrescribir el archivo original. Otro error es cargar todo el libro cuando solo se necesitan cuatro columnas.
Conclusión
Importar Excel con Pandas es sencillo, pero un flujo fiable necesita inspección, selección de columnas, normalización, conversión de tipos y validación. Usa read_excel con parámetros explícitos, conserva el origen de los datos y exporta una versión limpia. Así conviertes una tarea manual y frágil en un proceso automatizado, comprobable y fácil de mantener.






