@polotno/pptx-export
v0.1.1
Published
Convert Polotno JSON into PPTX file
Readme
Polotno to PPTX
Convert Polotno JSON into PowerPoint PPTX files. Works in Node.js and the browser.
The export is editable-first: text becomes real PowerPoint text runs, simple figures become native shapes, tables become native tables. Only things PPTX can't represent (complex shapes, gradients, filters, masks) are rasterized to images.
npm install @polotno/pptx-exportUsage
One import works everywhere — the package ships separate Node and browser builds and your bundler/runtime picks the right one automatically.
Browser — download the file
import { jsonToPPTX } from '@polotno/pptx-export';
const json = store.toJSON();
// triggers a "design.pptx" download
await jsonToPPTX(json, 'design.pptx');Node.js — save the file
import fs from 'fs';
import { jsonToPPTX } from '@polotno/pptx-export';
const json = JSON.parse(fs.readFileSync('./design.json'));
await jsonToPPTX(json, 'design.pptx');In-memory output
import { jsonToPPTXBytes, jsonToPPTXBlob } from '@polotno/pptx-export';
const bytes = await jsonToPPTXBytes(json); // Uint8Array, works everywhere
const blob = await jsonToPPTXBlob(json); // Blob, browser and Node 18+If your tooling resolves the wrong build (or you want to be explicit), pick one directly:
import { jsonToPPTX } from '@polotno/pptx-export/node';
// or
import { jsonToPPTX } from '@polotno/pptx-export/browser';Options
All functions accept an optional last argument:
await jsonToPPTX(json, 'design.pptx', {
// pixels-per-inch for px → inch/pt conversion.
// Defaults to json.dpi, then 72.
dpi: 72,
// supersampling factor for rasterized elements (default 2)
rasterScale: 2,
});Feature support
| Polotno feature | PPTX output |
| --- | --- |
| Text (incl. rich HTML: bold/italic/underline/strike, per-span color/font/size) | Native text runs |
| Text align / vertical align / line height / letter spacing / transform | Native |
| Lists (<ul>/<ol>, nesting, Quill data-list/ql-indent-N) | Native PowerPoint bullets & numbering |
| Text outline, shadow, background | Native |
| Figures: rect, circle, triangle, rightTriangle, diamond, pentagon, hexagon, star, cross, arrows, heart1, cloud | Native preset shapes (editable in PowerPoint) |
| Other figures (blobs, decorative shapes) | Rasterized PNG |
| Gradients (fill, page background) | Rasterized (PPTX has no gradient API in pptxgenjs) |
| Images: crop, flip, rotation, opacity, shadow | Native |
| Images: corner radius, border, filters (blur/sepia/grayscale/brightness/custom), masks | Composited to PNG |
| GIF | Animated when no effects applied; otherwise static |
| SVG (incl. colorsReplace) | Rasterized PNG |
| Lines with arrow heads & dash | Native line shapes |
| Tables (merged cells, per-cell styles & borders) | Native tables |
| Video | Embedded slide media |
| Groups | Children rendered with composed opacity |
| Page background (color / image / gradient) | Native background |
| Animations: fade / move / zoom (enter & exit) | Native effects (Fade, Fly In/Out, Zoom) that auto-play on slide entry |
| Animations: rotate / blink / bounce (loop) | Approximated with repeating emphasis effects (Spin, opacity pulse, Grow/Shrink) |
Known limitations
- Fonts are not embedded. PPTX font embedding is not supported by the underlying generator. Font names are passed through — the font must be installed on the viewing machine, or PowerPoint substitutes it.
- Curved text renders straight (with a warning).
- Gradient text fill renders with the first gradient stop color.
- Per-line text background becomes a whole-box background.
- Rotated tables render unrotated (PPTX tables can't rotate).
- Per-page sizes are not supported by PPTX — all slides use the document size.
page.bleedhas no PPTX equivalent and is ignored.- Animations play automatically on slide entry; slides still advance on click (no auto-advance from
page.duration). Exit animations are scheduled atpage.duration − duration − delay.cameraZoomhas no PPTX equivalent and is skipped with a warning.
Development
npm run build # build lib/index.js (Node) + lib/browser.js (browser) via tsup
npm test # run tests
npm run dev # start demo app at http://localhost:5173Tests
- Structural tests (
tests/features.test.ts,tests/render.test.js) unzip the generated PPTX and assert on the slide XML. They run everywhere. - Visual snapshot tests (
tests/pptx.test.js) convert the PPTX to PDF with LibreOffice, render PNGs and compare against baselines. They skip automatically when LibreOffice is not installed (brew install --cask libreofficeon macOS). Refresh baselines withnpm run test:update-snapshots.
LibreOffice's PPTX rendering differs from PowerPoint's — visual snapshots are regression tests, not proof of PowerPoint fidelity. Spot-check important changes in PowerPoint or Keynote.
