Skip to content
SP StackPractices
beginner Por StackPractices

Analizar Archivos Excel

Cómo leer y escribir archivos Excel (.xlsx) en Python, Java y JavaScript.

Temas: data

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Visión General

Los archivos Excel (.xlsx) siguen siendo el formato dominante para reportes de negocio, exports de datos y modelado financiero. Analizar Excel programáticamente habilita ingestión automatizada de datos, generación de reportes y pipelines de validación. Esta recipe cubre lectura, escritura y formateo de spreadsheets en Python, JavaScript y Java.

Cuándo Usar

Usa este recurso cuando:

  • Importes datos de usuarios de negocio que entregan archivos Excel en lugar de CSV
  • Generes reportes formateados con múltiples hojas, gráficos y estilos
  • Valides exports de datos contra bases de datos source-of-truth
  • Conviertas flujos de trabajo legacy basados en Excel a pipelines automatizados

Solución

Python

# openpyxl es el estándar para archivos .xlsx modernos
# pip install openpyxl
from openpyxl import load_workbook

wb = load_workbook('data.xlsx')
ws = wb.active

for row in ws.iter_rows(min_row=2, values_only=True):
    print(row)
# Escribir archivos Excel
from openpyxl import Workbook

wb = Workbook()
ws = wb.active
ws.title = "Ventas"
ws.append(["Producto", "Cantidad", "Precio"])
ws.append(["Widget", 100, 19.99])
wb.save('output.xlsx')

JavaScript

// xlsx (SheetJS) es la librería Excel más popular para Node.js
// npm install xlsx
import xlsx from 'xlsx';

const workbook = xlsx.readFile('data.xlsx');
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = xlsx.utils.sheet_to_json(sheet);
console.log(data);
// Escribir archivos Excel
import xlsx from 'xlsx';

const ws = xlsx.utils.aoa_to_sheet([['Nombre', 'Edad'], ['Alice', 30]]);
const wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, ws, 'Personas');
xlsx.writeFile(wb, 'output.xlsx');

Java

// Apache POI es el estándar para Excel en Java
// Maven: org.apache.poi:poi-ooxml
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;

public class ExcelParser {
    public static void main(String[] args) throws Exception {
        try (Workbook wb = new XSSFWorkbook(new FileInputStream("data.xlsx"))) {
            Sheet sheet = wb.getSheetAt(0);
            for (Row row : sheet) {
                for (Cell cell : row) {
                    System.out.print(cell.toString() + "\t");
                }
                System.out.println();
            }
        }
    }
}

Explicación

Los archivos Excel son archivos ZIP que contienen XML siguiendo la especificación Open XML. Las librerías abstraen esta complejidad en APIs de sheet, row y cell. openpyxl (Python) soporta características modernas de .xlsx como gráficos, imágenes y formato condicional. xlsx (JS) es ligera y soporta lectura y escritura en browser y Node.js. Apache POI (Java) es el estándar enterprise pero tiene mayor consumo de memoria.

Al leer, decide entre values_only=True (Python) o sheet_to_json (JS) para obtener valores planos, versus acceder a objetos de celda para formato, fórmulas y metadata. Para archivos grandes (>10k filas), usa lectores streaming para evitar cargar todo el workbook en memoria.

Variantes

TecnologíaLibreríaEnfoqueNotas
Pythonopenpyxlload_workbook()Soporte completo, lee/escribe .xlsx
Pythonpandasread_excel()Rápido para análisis de datos, envuelve openpyxl
Pythonxlrdopen_workbook()Solo .xls legacy, no recomendado para .xlsx
JavaScriptxlsx (SheetJS)readFile() / writeFile()Browser + Node, soporta export CSV/JSON
JavaApache POIXSSFWorkbookEstándar enterprise, soporta fórmulas y gráficos
JavaFastExcelAPI StreamingAlternativa de baja memoria a POI para archivos grandes

Mejores Prácticas

  • Usa read_only=True en openpyxl para archivos grandes solo-lectura para reducir uso de memoria
  • Valida nombres de hojas antes de acceder; archivos provistos por usuarios pueden tener nombres inesperados
  • Maneja celdas mergeadas explícitamente: Las librerías suelen retornar None para rangos mergeados excepto la celda superior-izquierda
  • Prefiere .xlsx sobre .xls: El formato moderno tiene límites de fila mayores y mejor compresión
  • Cierra handles de archivo con context managers (with en Python, try-with-resources en Java)

Errores Comunes

  • Usar xlrd para archivos .xlsx: xlrd eliminó soporte .xlsx en versión 2.0; usa openpyxl en su lugar
  • No manejar celdas con fórmulas: Las celdas fórmula retornan 0 o #VALUE! a menos que se evalúen o cacheen
  • Ignorar tipos de datos: Excel almacena fechas como números seriales; conviértelas explícitamente a datetime
  • Cargar workbooks enteros en memoria: Para archivos > 50 MB, usa APIs streaming para evitar OOM
  • Hard-codear índices de columna: Usa mapeo de fila header (e.g., {'Nombre': 0, 'Edad': 1}) para sobrevivir reordenamiento de columnas

Preguntas Frecuentes

¿Cómo leo archivos Excel grandes sin quedarme sin memoria?

Usa openpyxl con read_only=True en Python, FastExcel streaming en Java, o procesa archivos en chunks con xlsx en Node.js. Otra aproximación es convertir a CSV primero y luego hacer streaming del CSV, aunque pierdes formato y fórmulas.

¿Puedo preservar formato al escribir archivos Excel?

Sí. openpyxl soporta fuentes, rellenos, bordes y formatos numéricos vía el módulo openpyxl.styles. Apache POI tiene clases CellStyle y Font. xlsx (SheetJS) soporta estilos en su versión Pro; la versión community está limitada a datos raw.

¿Cómo manejo fechas correctamente al analizar Excel?

Excel almacena fechas como números de punto flotante (días desde 1900 o 1904). openpyxl retorna objetos datetime cuando data_only=True está seteado y los valores están cacheados. pandas convierte automáticamente columnas de fecha si se especifica parse_dates. En Java, usa DataFormatter para renderizar valores de celda como strings, luego parsea con DateTimeFormatter.