Export PPTX
Два режима. Выбирай по запросу.
Режим 1: screenshots (надёжно, не редактируется)
Каждый слайд → PNG → вставка в пустой PPTX. Pixel-perfect, но текст внутри картинки.
Зависимости: Node + Playwright + python-pptx + Pillow (или JS-аналог).
npm i -D playwright pptxgenjs
npx playwright install chromium
Скрипт templates/pptx-screenshots.mjs — рендерит слайды через тот же путь, что export-png, и собирает их через pptxgenjs:
import pptxgen from 'pptxgenjs';
import { chromium } from 'playwright';
import { pathToFileURL } from 'node:url';
import path from 'node:path';
const [, , file, out = 'deck.pptx'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1920, height: 1080 }});
await page.goto(pathToFileURL(path.resolve(file)).href, { waitUntil: 'networkidle' });
const total = await page.evaluate(() => document.querySelector('deck-stage').total);
await page.evaluate(() => document.querySelector('deck-stage').setAttribute('noscale', ''));
const pres = new pptxgen();
pres.layout = 'LAYOUT_WIDE'; // 13.33×7.5 inch ~ 1920×1080
for (let i = 0; i < total; i++) {
await page.evaluate(idx => document.querySelector('deck-stage').go(idx), i);
await page.waitForTimeout(600);
const buf = await page.screenshot({ type: 'png' });
const slide = pres.addSlide();
slide.background = { data: 'data:image/png;base64,' + buf.toString('base64') };
}
await pres.writeFile({ fileName: out });
await browser.close();
console.log('✓', out);
Режим 2: editable (текст и фигуры — нативные)
Сложнее. Идея: пройти по DOM каждого слайда, для каждого text-node создать slide.addText(...), для прямоугольника — slide.addShape(...), для картинки — slide.addImage(...).
pptxgenjs это умеет. Но 1:1 не получится — отказывайся от градиентов, теней, нестандартных шрифтов. Хорошо работает для деков, где макет = заголовок + текст + 1–2 фигуры.
Алгоритм:
- Запусти страницу в Playwright.
- На каждом слайде через
page.evaluate собери список объектов:[
{ type: 'text', x, y, w, h, text, font, size, color, bold, align },
{ type: 'rect', x, y, w, h, fill, stroke },
{ type: 'image', x, y, w, h, src },
]
Координаты — относительно слайда, в пикселях, потом конвертируй в дюймы (px / 96).
- Для каждого объекта вызови соответствующий
slide.addX(...).
pres.writeFile({ fileName }).
Готовый экстрактор писать заново не нужно — он лежит в соседнем навыке:
../pptx-editable-extractor/templates/extract.mjs (Playwright, node extract.mjs <html> [--slide-selector "deck-stage > section"] [--width 1920] [--height 1080] → slides.json),
а сборка из этого JSON — ../pptx-editable-extractor/templates/build_pptx.py.
Это черновик: для сложных макетов потребуется ручная подкрутка.
Что выбирать когда
| Ситуация |
Режим |
| Дек уйдёт в PowerPoint, его будут править |
editable (с компромиссами по визуалу) |
| Просто переслать как PPTX, без правок |
screenshots |
| В деке много кастомных эффектов / SVG |
screenshots, иначе сломается |
| Текст должен искаться / переводиться в PowerPoint |
editable |
Замечания
- Шрифты: PowerPoint использует системные шрифты получателя. Если в HTML Helvetica Neue, а у получателя Windows — он увидит fallback. Закладывай это в выбор шрифтов.
- 16:9 в PowerPoint —
LAYOUT_WIDE (13.33×7.5 in). 4:3 — LAYOUT_STANDARD (10×7.5 in).
- Если используешь Google Fonts — заранее предупреди пользователя, что PPT не подтянет их и шрифт подменится.
Legacy reference
Прежняя расширенная версия скилла (дерево @2026-04-30) сохранена целиком в references/legacy-export-pptx.md. Секции там: Зависимости, Каркас, Workflow целиком, PPTX размеры, Альтернативный путь: LibreOffice, Когда нужен редактируемый PPTX, Скрытые слайды, Speaker notes, Метаданные, Антипаттерны.
1---2name: export-pptx3description: HTML-дек в PPTX: режим картинок (надёжный) или редактируемый (нативный текст, pptxgenjs). Триггеры: «html в pptx», «выгрузи в PowerPoint».4---56# Export PPTX78Два режима. Выбирай по запросу.910## Режим 1: screenshots (надёжно, не редактируется)1112Каждый слайд → PNG → вставка в пустой PPTX. Pixel-perfect, но текст внутри картинки.1314**Зависимости:** Node + Playwright + python-pptx + Pillow (или JS-аналог).1516```bash17npm i -D playwright pptxgenjs18npx playwright install chromium19```2021Скрипт `templates/pptx-screenshots.mjs` — рендерит слайды через тот же путь, что `export-png`, и собирает их через **pptxgenjs**:2223```js24import pptxgen from 'pptxgenjs';25import { chromium } from 'playwright';26import { pathToFileURL } from 'node:url';27import path from 'node:path';2829const [, , file, out = 'deck.pptx'] = process.argv;30const browser = await chromium.launch();31const page = await browser.newPage({ viewport: { width: 1920, height: 1080 }});32await page.goto(pathToFileURL(path.resolve(file)).href, { waitUntil: 'networkidle' });3334const total = await page.evaluate(() => document.querySelector('deck-stage').total);35await page.evaluate(() => document.querySelector('deck-stage').setAttribute('noscale', ''));3637const pres = new pptxgen();38pres.layout = 'LAYOUT_WIDE'; // 13.33×7.5 inch ~ 1920×10803940for (let i = 0; i < total; i++) {41 await page.evaluate(idx => document.querySelector('deck-stage').go(idx), i);42 await page.waitForTimeout(600);43 const buf = await page.screenshot({ type: 'png' });44 const slide = pres.addSlide();45 slide.background = { data: 'data:image/png;base64,' + buf.toString('base64') };46}4748await pres.writeFile({ fileName: out });49await browser.close();50console.log('✓', out);51```5253## Режим 2: editable (текст и фигуры — нативные)5455Сложнее. Идея: пройти по DOM каждого слайда, для каждого text-node создать `slide.addText(...)`, для прямоугольника — `slide.addShape(...)`, для картинки — `slide.addImage(...)`.5657`pptxgenjs` это умеет. Но 1:1 не получится — отказывайся от градиентов, теней, нестандартных шрифтов. Хорошо работает для деков, где макет = заголовок + текст + 1–2 фигуры.5859Алгоритм:60611. Запусти страницу в Playwright.622. На каждом слайде через `page.evaluate` собери список объектов:63 ```js64 [65 { type: 'text', x, y, w, h, text, font, size, color, bold, align },66 { type: 'rect', x, y, w, h, fill, stroke },67 { type: 'image', x, y, w, h, src },68 ]69 ```70 Координаты — относительно слайда, в пикселях, потом конвертируй в дюймы (`px / 96`).713. Для каждого объекта вызови соответствующий `slide.addX(...)`.724. `pres.writeFile({ fileName })`.7374Готовый экстрактор писать заново не нужно — он лежит в соседнем навыке:75`../pptx-editable-extractor/templates/extract.mjs` (Playwright, `node extract.mjs <html>76[--slide-selector "deck-stage > section"] [--width 1920] [--height 1080]` → `slides.json`),77а сборка из этого JSON — `../pptx-editable-extractor/templates/build_pptx.py`.78Это **черновик**: для сложных макетов потребуется ручная подкрутка.7980## Что выбирать когда8182| Ситуация | Режим |83|---|---|84| Дек уйдёт в PowerPoint, его будут править | editable (с компромиссами по визуалу) |85| Просто переслать как PPTX, без правок | screenshots |86| В деке много кастомных эффектов / SVG | screenshots, иначе сломается |87| Текст должен искаться / переводиться в PowerPoint | editable |8889## Замечания9091- Шрифты: PowerPoint использует системные шрифты получателя. Если в HTML Helvetica Neue, а у получателя Windows — он увидит fallback. Закладывай это в выбор шрифтов.92- 16:9 в PowerPoint — `LAYOUT_WIDE` (13.33×7.5 in). 4:3 — `LAYOUT_STANDARD` (10×7.5 in).93- Если используешь Google Fonts — заранее предупреди пользователя, что PPT не подтянет их и шрифт подменится.9495## Legacy reference9697Прежняя расширенная версия скилла (дерево @2026-04-30) сохранена целиком в `references/legacy-export-pptx.md`. Секции там: Зависимости, Каркас, Workflow целиком, PPTX размеры, Альтернативный путь: LibreOffice, Когда нужен **редактируемый** PPTX, Скрытые слайды, Speaker notes, Метаданные, Антипаттерны.