Files
fn_registry/docs/capabilities/excel.md
T
egutierrez 927437a8d8 feat(infra): grupo claude-fleet — FleetView TUI + orquestacion de Claudes
Sistema FleetView para centralizar la flota de procesos Claude Code vivos en una
sola ventana kitty + tmux (socket aislado -L fleet) con un panel TUI:

- list_claude_fleet (+ tipo claude_fleet): escanea ~/.claude/sessions + goals +
  runtime, valida procesos vivos (anti-PID-reciclado), join por sessionId.
- list_resumable_claudes (+ tipo resumable_claude): sesiones cerradas reanudables.
- wrappers tmux: tmux_new_claude_window (con --resume), tmux_swap_window_into_console
  (preserva ancho del sidebar), tmux_map_claude_panes.
- launch_kittyclaude: comando entrypoint; instala atajos alt+flechas/enter/n/0/k/r,
  mouse on, remain-on-exit off; fija el ancho del sidebar con hooks.
- docs/capabilities/claude-fleet.md + entrada en el INDEX.

Incluye ademas funciones datascience en progreso (excel/duckdb/postgres) y ajustes
varios de docs e infra de otra sesion, agrupados aqui para no perderlos.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 00:04:41 +02:00

5.4 KiB

Capability: excel

CRUD de hojas de cálculo Excel (.xlsx) desde el registry con openpyxl: escribir libros multi-hoja, actualizar una hoja sin destruir las demás (preservando columnas editadas a mano), leer a estructuras en memoria o a markdown, añadir gráficos nativos, e ingerir una hoja a DuckDB.

Es el extremo Excel del stack de datos Excel → DuckDB → Postgres → visualización: el Excel sirve como entrada (lo que produce un humano o un export) y como entregable (un libro con gráficos que viaja por email/disco, sin servidor). El round-trip humano lo cubre upsert_xlsx_sheet, que conserva las columnas que las personas rellenan a mano mientras regenera las columnas calculadas.

Funciones

ID Firma Que hace
write_xlsx_sheets_py_infra write_xlsx_sheets(out_path, sheets, header_bold=True, autofit=True, freeze_header=True) -> str Escribe (o sobrescribe) un libro .xlsx multi-hoja desde un dict {nombre_hoja: datos}. Cada hoja acepta list[list] (primera fila = headers) o {"headers": [...], "rows": [[...]]}. Cabecera en negrita, auto-ancho, freeze de cabecera. Devuelve la ruta absoluta.
upsert_xlsx_sheet_py_infra upsert_xlsx_sheet(xlsx_path, sheet_name, records, columns, key_col="", preserve_cols=None, formulas=None, backup=True, ...) -> dict Actualiza NO destructivamente UNA hoja: reescribe solo sheet_name y conserva las demás. Antes de limpiar, lee por key_col las columnas de trabajo manual (preserve_cols) y las reescribe ganando sobre los datos nuevos. Cabecera estilizada, freeze, autofilter, fórmulas por columna, backup .bak.
read_xlsx_py_infra read_xlsx(path, sheet=None, max_rows=None, header=True) -> dict Lee un .xlsx a memoria (NO a markdown). Devuelve {status, sheets: {nombre: {headers, rows}}}. sheet=None lee todas. Tipos de celda: fechas→ISO, int/float, bool, None, fórmulas (valor calculado, data_only=True). Espejo en lectura de write_xlsx_sheets.
excel_to_markdown_py_core excel_to_markdown(path, max_rows_per_sheet=1000) -> str Convierte .xlsx/.xls/.xlsm a markdown, cada hoja como sección H2. Para inspección rápida / pegar en un prompt o nota.
add_xlsx_chart_py_infra add_xlsx_chart(xlsx_path, sheet_name, chart_type, data_range, cats_range=None, anchor='H2', title='', x_title='', y_title='') -> dict Añade un gráfico nativo (bar/line/pie/scatter) a una hoja EXISTENTE, refiriendo rangos de celdas ya escritos (notación Excel 'C1:C7'). anchor = celda destino. La pieza para generar hojas Excel CON gráficos.
excel_to_duckdb_py_infra excel_to_duckdb(xlsx_path, duckdb_path, table, sheet=None, mode='replace') -> dict Ingesta una hoja del .xlsx a una tabla DuckDB con la extensión nativa excel de DuckDB. Puente Excel→DuckDB. También etiquetada en el grupo duckdb.

Ejemplo canónico

Escribir un libro, añadirle un gráfico y releerlo a memoria (verificado):

cd /home/enmanuel/fn_registry
python/.venv/bin/python3 - <<'PYEOF'
import sys
sys.path.insert(0, "python/functions")
from infra import write_xlsx_sheets, add_xlsx_chart, read_xlsx

xlsx = "/tmp/ventas.xlsx"
write_xlsx_sheets(xlsx, {"ventas": [
    ["mes", "categoria", "importe"],
    ["2026-01", "neumaticos", 12500.50],
    ["2026-02", "neumaticos", 15800.75],
    ["2026-03", "neumaticos", 18200.00],
]})

# Gráfico de barras del importe por mes, anclado en la celda G2
add_xlsx_chart(xlsx, "ventas", "bar", data_range="C1:C4", cats_range="A2:A4",
               anchor="G2", title="Importe por mes", y_title="EUR")

rd = read_xlsx(xlsx, sheet="ventas")
print(rd["sheets"]["ventas"]["headers"], len(rd["sheets"]["ventas"]["rows"]))
PYEOF

Gotchas del grupo

  • openpyxl no evalúa fórmulas. read_xlsx con data_only=True devuelve el valor cacheado por la última app que guardó el libro (Excel/LibreOffice). Un .xlsx con fórmulas escritas por openpyxl y nunca abierto en una hoja de cálculo devuelve None en esas celdas.
  • add_xlsx_chart exige libro y hoja existentes: no crea el .xlsx ni escribe datos; los rangos deben apuntar a celdas ya escritas. Flujo: write_xlsx_sheetsadd_xlsx_chart.
  • Rangos 1-indexed, notación Excel ('C1:C7'). Si data_range incluye la fila de cabecera, el nombre de la serie sale de esa celda (titles_from_data). scatter usa data_range como Y y cats_range como X; pie ignora los títulos de eje.
  • Carga en memoria: openpyxl carga el libro entero; para libros muy grandes considera ingerir a DuckDB (excel_to_duckdb) y consultar allí.
  • upsert_xlsx_sheet es la vía para datos editados por humanos: si una persona rellena columnas a mano, pásalas en preserve_cols para que un re-volcado no las pise.

Fronteras

  • NO es una herramienta de BI ni de dashboards. Para visualización interactiva/compartida: Metabase, Evidence (sobre DuckDB) o gráficos embebidos con add_xlsx_chart para el caso "todo en el .xlsx".
  • El análisis pesado (agregaciones, joins, histórico) NO se hace en Excel: ingiere a DuckDB con excel_to_duckdb y usa el grupo duckdb.
  • NO cubre .csv de entrada con encodings legacy — eso es safe_read_csv_fallback_py_core.

Relación con otros grupos

  • duckdbexcel_to_duckdb es el puente de entrada; el motor analítico vive allí.
  • postgres — la salida hacia BI pasa por duckdb_to_postgres (grupo duckdb/postgres).
  • metabase — consume los datos una vez en Postgres.