Creación, edición y análisis de PPTX
Un .pptx es un archivo ZIP de archivos XML. Elige tu enfoque según la tarea:
| Tarea | Enfoque |
|---|---|
| Crear una presentación nueva | Escribe un script de pptxgenjs — consulta las trampas a continuación |
| Editar una presentación existente, o construir desde una plantilla | descomprimir → editar ppt/slides/slideN.xml → comprimir |
| Leer contenido | markitdown deck.pptx (un bloque por diapositiva bajo los marcadores <!-- Slide number: N -->); cuadrícula visual: python scripts/thumbnail.py deck.pptx |
Scripts
Las rutas son relativas al directorio de esta habilidad. Todo lo demás es Python puro, node o shell.
| Script | Qué hace |
|---|---|
scripts/thumbnail.py deck.pptx [prefijo] | Cuadrícula etiquetada de cada diapositiva, para elegir diseños de plantilla. Solo .pptx. Pasa prefijo — por defecto es thumbnails, lo que sobrescribe las cuadrículas de cualquier otra presentación en el mismo directorio |
scripts/add_slide.py descomprimido/ slide2.xml [--after slideN.xml] | Duplica una diapositiva (o un slideLayoutN.xml) con toda la gestión de paquetes. También acepta un .pptx directamente con -o out.pptx |
scripts/clean.py descomprimido/ | Elimina diapositivas, medios y rels no referenciados. Ejecutar después de que <p:sldIdLst> esté finalizado |
scripts/office/validate.py deck.pptx [--original src.pptx] | Comprobaciones de esquema, relaciones, tipos de contenido, gráficos y diapositivas; cada fallo indica su corrección. Pasa --original para cualquier presentación derivada de plantilla — compara las comprobaciones de esquema con la plantilla, para que los propios errores XSD de la plantilla no se lean como tuyos |
scripts/office/soffice.py --headless --convert-to pdf deck.pptx | Wrapper de LibreOffice — soffice desnudo se cuelga en este sandbox |
Crear con pptxgenjs — trampas
pptxgenjs está preinstalado — no ejecutes npm install primero; escribe el script y usa require('pptxgenjs') directamente. Solo si ese require falla: npm install pptxgenjs. El modelo conoce la API; estos son los puntos conflictivos:
- Configura
pres.layoutantes de añadir diapositivas. El lienzo predeterminado esLAYOUT_16x9= 10" × 5.625", no 13.3" de ancho. Las coordenadas fuera del borde se escriben, no se recortan; la forma simplemente no está en la diapositiva. (LAYOUT_WIDEes 13.3" × 7.5".) - Colores hexadecimales: nunca
#, nunca 8 dígitos.color: "FF0000". Tanto"#FF0000"como alfa incluido en el hex ("00000020") corrompen el archivo. Para translucidez:transparency: 0-100en rellenos e imágenes,opacity: 0.0-1.0en sombras — cada uno se ignora silenciosamente en el otro. - pptxgenjs muta los objetos de opciones en el lugar (convierte valores a EMU en el primer uso). Nunca compartas un objeto
shadow/opciones entre dos llamadasadd*— crea un objeto nuevo cada vez. - El
offsetde la sombra debe ser ≥ 0 — un offset negativo corrompe el archivo. Para proyectar una sombra hacia arriba, usaangle: 270con un offset positivo. letterSpacingse ignora silenciosamente — la opción real escharSpacing.- Listas:
bullet: trueen cada elemento, nunca un•literal (representa viñetas dobles). ConfigurabreakLine: trueen cada elemento del array excepto el último. Separa párrafos con viñetas conparaSpaceAfter, nolineSpacing(grandes espacios). - Un
new pptxgen()por archivo de salida — nunca reutilices una instancia. rectRadiussolo funciona enROUNDED_RECTANGLE, no enRECTANGLE.- Los rellenos degradados no son compatibles — usa una imagen degradada como fondo.
- Los cuadros de texto tienen relleno interno incorporado — configura
margin: 0cuando el texto deba alinearse con una forma, línea o icono en la misma x. - Las notas del orador van en
slide.addNotes("...")(texto plano, una vez por diapositiva), nunca en un cuadro de texto en la diapositiva. - Mantén los gráficos nativos. Usa
addChart()para todo lo que PowerPoint puede graficar (pasa un array de{type, data, options}para combinaciones). Para características nativas de PowerPoint que la biblioteca no expone (líneas de tendencia, barras de error), calcula la serie adicional tú mismo o procesa posteriormente el OOXML generado; no recurras a una imagen renderizada. Solo los tipos de gráficos que PowerPoint no tiene de forma nativa (Sankey, red, acorde) van como imágenes. - Los gráficos predeterminados se renderizan desnudos — sin título, sin etiquetas de datos, paleta anticuada. Configura
showTitle+title,showValue: true+dataLabelPosition,chartColors: [...]desde tu paleta, y silencia el marco (catAxisLabelColor/valAxisLabelColor,valGridLine: { color, size },catGridLine: { style: "none" },showLegend: falsepara una sola serie). - **En un gráfico de barras apiladas o columnas,
dataLabelPositiondebe serctr,inEndoinBase.outEndcorrompe el archivo. - Una serie combinada que usa
secondaryValAxis/secondaryCatAxisnecesita tantovalAxescomocatAxesen las opciones del gráfico, dos entradas cada uno. Sin ellos, pptxgenjs escribe ids de ejes que nunca declara, y PowerPoint descarta ese gráfico e informa que el archivo está corrupto. Proporcionar solovalAxesno es suficiente. - Después de
writeFile(), ejecutapython scripts/office/validate.py deck.pptx. Informa de los dos fallos anteriores de gráficos y los defectos de XML de diapositivas que PowerPoint rechaza, y nombra la corrección para cada uno. Arréglelos en su generador, no editando manualmente el XML empaquetado. - Nunca reordenes los hijos de
<p:presentation>. pptxgenjs escribe<p:notesMasterIdLst>justo después de<p:sldIdLst>y apunta ambos maestros a una parte de tema. PowerPoint lo lee felizmente — mueve el elemento y la misma presentación se vuelve inabrible. - Iconos: renderiza
react-iconsa SVG (ReactDOMServer.renderToStaticMarkup), rasteriza consharpa ≥256px, e inserta medianteaddImage({ data: "image/png;base64," + buf.toString("base64") })— el prefijoimage/png;base64,es obligatorio (react-icons,react,react-domysharpestán preinstalados —npm install react-icons react react-dom sharpsolo si un require falla).
Editar presentaciones y plantillas existentes
Elige los diseños primero: python scripts/thumbnail.py template.pptx template-thumbs escribe una cuadrícula etiquetada de cada diapositiva e imprime los archivos que creó — template-thumbs.jpg, dividido en template-thumbs-N.jpg después de 12 diapositivas. Pasa siempre ese segundo argumento, nombrado después de la presentación. Por defecto es thumbnails, así que dos presentaciones con miniaturas en el mismo directorio sobrescriben silenciosamente las cuadrículas del otro — las del primero simplemente desaparecen (solo análisis de plantilla; la revisión visual necesita las representaciones de resolución completa de Conversión a imágenes; solo acepta .pptx, así que copia un .potx a un nombre .pptx primero). Úsalo con markitdown para mapear cada sección de contenido a una diapositiva de plantilla, y varía los diseños — no pongas cada sección en la misma diapositiva de título y viñetas.
python3 -c "import sys,zipfile; zipfile.ZipFile(sys.argv[1]).extractall('descomprimido')" deck.pptx
python scripts/add_slide.py descomprimido/ slide2.xml --after slide2.xml # duplicar una diapositiva (o slideLayoutN.xml); imprime la ruta de la nueva diapositiva
# reordenar / eliminar diapositivas = editar <p:sldIdLst> en ppt/presentation.xml
python scripts/clean.py descomprimido/ # después de eliminaciones: elimina diapositivas huérfanas, medios, rels
# editar contenido de diapositiva en ppt/slides/slideN.xml
(cd descomprimido && rm -f ../out.pptx && zip -Xr ../out.pptx .) # comprimir DESDE DENTRO del directorio; rm primero o las partes eliminadas sobreviven
python scripts/office/validate.py out.pptx --original deck.pptx
- Haz todo el trabajo estructural — añadir, eliminar, reordenar — antes de editar el contenido de cualquier diapositiva.
add_slide.pycopia un archivo de diapositiva textualmente, así que duplicar después de editar clona el contenido editado; yclean.pyelimina cualquier diapositiva que falte en<p:sldIdLst>, incluida una que acabas de escribir. - Nunca copies un archivo de diapositiva a mano —
add_slide.pyhace todos los registros que necesita una nueva diapositiva e informa de lo que creó (Created ppt/slides/slide17.xml from slide2.xml). También funciona directamente en un archivo:add_slide.py deck.pptx slide2.xml -o out.pptx— pasa-o, o sobrescribe la presentación de entrada en el lugar. Una diapositiva duplicada todavía referencia las partes de gráfico/SmartArt/objeto incrustado de su fuente en lugar de clonarlas, así que editar el gráfico de una diapositiva cambia el de la otra. - Si usas
python-pptx, tres cosas que no hará: duplicar una diapositiva (su único punto de entrada esadd_slide(layout)), preservar el formato a través detext_frame.text = "..."(eso colapsa el párrafo a una sola ejecución sin estilo — asignarun.texten su lugar), o leer el SVG/EMF que la mayoría del arte de plantilla usa (add_picturelanzaUnidentifiedImageError). - El
.pptheredado debe convertirse primero:python scripts/office/soffice.py --headless --convert-to pptx file.ppt. Las plantillas.potxse desempaquetan y empaquetan de manera idéntica — mantén la extensión.potxen la salida. - Para reutilizar un icono o imagen de plantilla, duplica una diapositiva o diseño que ya lo contenga.
Al rellenar una plantilla:
- Si escribes una transformación XML, analiza con
defusedxml.minidom— el redondeo de OOXML a través dexml.etree.ElementTreereescribe los prefijos de espacio de nombres y corrompe la presentación. - Las ranuras de plantilla ≠ elementos de origen. Si la plantilla muestra 4 miembros del equipo y tienes 3, elimina todo el grupo del 4º miembro (caja de imagen + texto), no solo su texto — luego verifica si hay elementos visuales huérfanos en QA.
- Un
<a:p>por elemento de lista — nunca concatenes elementos en un solo párrafo. Copia el<a:pPr>hermano para preservar el espaciado, y ponb="1"en el<a:rPr>de títulos, encabezados de sección y etiquetas en línea (Estado:,Propietario:). - Deja que las viñetas hereden del diseño; solo añade
<a:buChar>,<a:buAutoNum>(numerado), o<a:buNone>para sobrescribir — nunca un•literal en el texto. - El texto con espacios al principio o al final necesita
xml:space="preserve"en su<a:t>.
Ideas de diseño
No crees diapositivas aburridas. Las viñetas simples sobre un fondo blanco no impresionarán a nadie. Considera ideas de esta lista para cada diapositiva.
Antes de empezar
- Elige una paleta de colores audaz e informada por el contenido: La paleta debe sentirse diseñada para ESTE tema. Si intercambiar tus colores en una presentación completamente diferente todavía "funcionara", no has hecho elecciones lo suficientemente específicas.
- Dominancia sobre igualdad: Un color debe dominar (60-70% de peso visual), con 1-2 tonos de apoyo y un acento nítido. Nunca des a todos los colores el mismo peso.
- Contraste oscuro/claro: Fondos oscuros para diapositivas de título + conclusión, claros para contenido (estructura "sándwich"). O comprométete con oscuro en toda la presentación para una sensación premium.
- Comprométete con un motivo visual: Elige UN elemento distintivo y repítelo — marcos de imagen redondeados, iconos en círculos de colores. Llévalo a través de cada diapositiva. No uses una barra de color o franja de acento como tu motivo (ver lista de Evitar).
Paletas de colores
Elige colores que coincidan con tu tema — no te limites al azul genérico. Usa estas paletas como inspiración:
| Tema | Primario | Secundario | Acento |
|---|---|---|---|
| Ejecutivo medianoche | 1E2761 (azul marino) | CADCFC (azul hielo) | FFFFFF (blanco) |
| Bosque y musgo | 2C5F2D (bosque) | 97BC62 (musgo) | F5F5F5 (crema) |
| Energía coral | F96167 (coral) | F9E795 (oro) | 2F3C7E (azul marino) |
| Terracota cálido | B85042 (terracota) | E7E8D1 (arena) | A7BEAE (salvia) |
| Degradado oceánico | 065A82 (azul profundo) | 1C7293 (verde azulado) | 21295C (medianoche) |
| Carbón minimalista | 36454F (carbón) | F2F2F2 (blanco roto) | 212121 (negro) |
| Confianza verde azulado | 028090 (verde azulado) | 00A896 (espuma de mar) | 02C39A (menta) |
| Baya y crema | 6D2E46 (baya) | A26769 (rosa polvoriento) | ECE2D0 (crema) |
| Calma salvia | 84B59F (salvia) | 69A297 (eucalipto) | 50808E (pizarra) |
| Cereza audaz | 990011 (cereza) | FCF6F5 (blanco roto) | 2F3C7E (azul marino) |
Para cada diapositiva
Cada diapositiva necesita un elemento visual — imagen, gráfico, icono o forma. Las diapositivas solo de texto son olvidables.
Opciones de diseño:
- Dos columnas (texto a la izquierda, ilustración a la derecha)
- Filas de icono + texto (icono en círculo de color, encabezado en negrita, descripción debajo)
- Cuadrícula 2x2 o 2x3 (imagen en un lado, cuadrícula de bloques de contenido en el otro)
- Imagen de sangría media (lado izquierdo o derecho completo) con superposición de contenido
Visualización de datos:
- Destacados de estadísticas grandes (números grandes 60-72pt con etiquetas pequeñas debajo)
- Columnas de comparación (antes/después, pros/contras, opciones lado a lado)
- Línea de tiempo o flujo de proceso (pasos numerados, flechas)
Pulido visual:
- Iconos en pequeños círculos de color junto a encabezados de sección
- Texto en cursiva para estadísticas clave o eslóganes
Tipografía
Los nombres de fuentes que escribes en el .pptx son renderizados por PowerPoint del usuario, no por este entorno. Tu QA visual renderiza a través de LibreOffice, que sustituye fuentes que no tiene — y para algunas fuentes el sustituto tiene diferentes anchos, por lo que tu vista previa de QA puede mostrar desbordamiento de texto (o ajuste) que la presentación real no tendrá. Para mantener tu QA confiable:
- Fuentes seguras (se renderizan fielmente en QA y vienen con Office): Arial, Calibri, Cambria, Times New Roman, Courier New, Bookman Old Style, Century Schoolbook. Úsalas para texto del cuerpo y cualquier cosa donde el ajuste importe.
- Encabezados con personalidad sin riesgo de QA: combina un encabezado serif de la lista segura (Cambria, Bookman Old Style, Century Schoolbook) con un cuerpo sans de la lista segura (Calibri o Arial). Obtienes contraste visual sin renunciar a comprobaciones de desbordamiento confiables.
- Si el usuario pide una fuente fuera de la lista segura (por ejemplo, Georgia o Trebuchet MS): úsala donde el usuario pidió, pero dimensiona esos contenedores con margen extra (~10%) y no confíes en el ajuste de texto de QA en esos elementos — la vista previa de esa fuente es aproximada. Si el usuario no ha especificado, prefiere fuentes de la lista segura para texto del cuerpo.
- Fuentes no confiables en QA (el sustituto tiene diferentes anchos — las comprobaciones de desbordamiento pueden ser incorrectas): Georgia, Trebuchet MS, Impact, Arial Black, Garamond, Consolas, Palatino Linotype. La sustitución de Calibri Light varía según el entorno; trata como no confiable en QA. Bien para títulos/acentos con margen; no confíes en el ajuste de texto de QA en estos.
- Nunca uses Aptos por defecto — el valor predeterminado posterior a 2023 de Office no tiene un sustituto compatible con métricas aquí y falta en instalaciones antiguas de Office, por lo que no es confiable en ambos extremos.
| Elemento | Tamaño |
|---|---|
| Título de diapositiva | 36-44pt negrita |
| Encabezado de sección | 20-24pt negrita |
| Texto del cuerpo | 14-16pt |
| Leyendas | 10-12pt atenuado |