A free PowerPoint add-in that exports the open deck to 31 formats with their options left in: pictures at any size, PDFs and handouts, video, HTML5, reveal.js, LaTeX Beamer, Markdown.
翻译准备中
插件TypeScript · JavaScriptGitHub @stoatworks-labs在线运营者未确认
试用过了吗? 点一下就好,无需登录。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证PowerPoint add-in: export a deck to images at any size, PDFs and handouts, video and GIF, an HTML5 presentation, reveal.js, LaTeX Beamer, Markdown and more, each with its own options.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗AI-assisted project. This codebase was created with Claude (Anthropic), directed and reviewed by a human author. Every format has been exported from a real deck inside PowerPoint for Mac and checked with independent tools; PowerPoint for Windows and on the web haven't been tried yet. See Status.
PowerPoint will save a deck as a PDF, a picture per slide or a video, and it asks you remarkably little about any of them. This add-in does all of those with the options left in (size, resolution, quality, slide range, letterboxing) and then carries on into the formats PowerPoint never got round to: a self-contained HTML5 presentation, reveal.js, LaTeX Beamer, Markdown and Marp, handouts and notes pages, a deck flattened to pictures for a playback machine that hasn't got your fonts, and a few more.
It's an Office task-pane add-in, so the same thing runs in PowerPoint for Mac, Windows and the web. PowerPoint draws every slide itself, at exactly the size each format asks for; the add-in reads the rest (notes, hidden slides, transitions, links, video) out of the deck. Everything happens in the pane. Nothing is uploaded.
The project page has the download and the user guide. The add-in is hosted at https://pptx-exporter-addin.stoatworks-labs.com, which has the install steps.
| Group | Formats |
|---|---|
| Images | PNG, JPEG, WebP, AVIF, TIFF (one per slide or multi-page; LZW, Deflate or PackBits), BMP, TGA, GIF, SVG with clickable links, contact sheet |
| Documents | PowerPoint's vector PDF (trimmed to a range or split per slide), picture PDF (keeps hidden slides and links), handouts 1/2/3/4/6/9 to a page, notes pages, Word notes document, OpenDocument |
| Web | HTML5 presentation with transitions, presenter view, links and the deck's own video; reveal.js; a scrolling page |
| Video | MP4 (H.264, HEVC, AV1) and WebM (VP9, VP8, AV1) with the deck's timings and captions from the notes; animated GIF; the deck's own video and sound files in a .zip (Video bundle) |
| Text | LaTeX Beamer (the slides as drawn, or rebuilt as editable LaTeX) or a LaTeX article with notes; Markdown, Marp, Pandoc/Quarto; an outline PowerPoint reads back in (RTF), OPML or text; speaker notes; CSV; JSON |
| PowerPoint | A copy as PPTX, PPSX or POTX, trimmed and cleaned (notes, comments, hidden slides, names); one file per slide; a flattened picture deck |
Every option for every format is in the user guide.
This release contains:
manifest.xml — Office add-in manifest (sideload into PowerPoint), 5 KBAll builds, checksums and release notes: github.com/stoatworks-labs/pptx-exporter-addin/releases.
localhost.manifest.xml.~/Library/Containers/com.microsoft.Powerpoint/Data/Documents/wef/, quit PowerPoint and
reopen it, then Home ▸ Add-ins ▸ Developer Add-ins ▸ Advanced Exporter.Measured in PowerPoint for Mac 16.112.3 on 2026-10-20:
Slide.getImageAsBase64 (PowerPointApi 1.8,
and this build reports 1.10) drew nine 1080p slides in under a second; a 4K slide takes about
0.2 s.InvalidArgument. The add-in finds that ceiling by bisection the first time it hits it, and
draws anything bigger from PowerPoint's vector PDF through pdf.js, which comes out as sharp at
8K as at 4K. A hidden slide isn't in that PDF, so at those sizes it is scaled up instead, and
the export notes say so.getFileAsync(Pdf), eight pages for nine
slides). Pages are matched to slides around them, and a range that includes a hidden slide
says it's missing rather than shifting every page after it by one.getFileAsync took 385.6 s for a
461 MB deck full of video (111 slices of 4 MB: 4.3 s to the first, then about 3.5 s each).
Every export starts by reading the deck, so a big one costs minutes before any format runs.npm install
npm run certs # trust a localhost certificate (Office needs HTTPS); lasts 30 days
npm run dev # https://localhost:3000
npm run sideload:mac # a dev manifest in PowerPoint's wef folder, then quit and reopen PowerPoint
npm test # vitest
npm run build # typecheck and build to dist/
npm run validate # Microsoft's manifest validator
The certificate from npm run certs expires after 30 days, and PowerPoint then refuses the dev
pane with "isn't signed by a valid security certificate". Run it again (--days 90 makes it last
longer).
Outside PowerPoint the pane runs against a stand-in host that draws slides crudely itself, so
every format can be driven in a browser: open
https://localhost:3000/taskpane.html?mock=/__fixtures/sample-16x9.pptx, or run
PLAIN_HTTP=1 npx vite --port 3001 for a browser that doesn't trust the dev certificate.
A dev pane, in PowerPoint or a browser, can be driven from the shell, which is how it was tested:
scripts/pane.sh info # host, API sets, codecs, the deck
scripts/pane.sh export '{"formats":{"png":{"size":"4k"},"pdf":{}},"includeHidden":true}'
scripts/pane.sh probe '{"widths":[3840,4096]}'
scripts/pane.sh reload
Output lands in .out/ and the pane's log in .out/pane.log. None of this is in a production
build. Run the dev server with NO_HMR=1 while doing this, or an edit reloads the pane in the
middle of an export.
npm test covers the deck parser, the encoders, page layout, the text formats and the Office
packages against the decks in test/fixtures/ (built by npm run fixtures with python-pptx).
Anything that needs a canvas or PowerPoint's renderer is checked in a browser or in PowerPoint,
through scripts/pane.sh, with the output checked by: libtiff (tiffinfo -D) and Pillow for
images, poppler (pdfinfo, pdftoppm, pdffonts) for PDFs, ffprobe and ffmpeg for video,
Tectonic for LaTeX, and scripts/check-office.py (python-pptx, python-docx, odfpy) for Office
files.
manifest.xml is the production manifest: every URL in it points at
https://pptx-exporter-addin.stoatworks-labs.com, and test/manifest.test.ts fails if one
points anywhere else or stops matching wrangler.toml. npm run build puts the pane, the
install page, the icons, _headers and a copy of the manifest in dist/.
deploy.yml publishes that as a Cloudflare Worker with static
assets on every push to main, then checks the live origin is serving the build it just made;
cf-run npm run deploy does the same from a laptop. The workflow needs the repo secret
CLOUDFLARE_API_TOKEN and the variable CLOUDFLARE_ACCOUNT_ID.
Releasing: bump package.json (and the lockfile), commit, tag vX.Y.Z and push the tag.
release.yml checks the tag against package.json, validates
the manifest, builds the Windows installer and attaches both to a GitHub release. Then, on the
Mac with the signing identity, npm run installer:mac and gh release upload vX.Y.Z release/*.pkg add the Mac installer and uninstaller (see Installers). The CSP in
public/_headers lets Office.js load from Microsoft's CDN and lets PowerPoint
on the web frame the pane; npm run serve:dist serves dist/ with those headers applied.
People expect an installer, the kind Slido has. Slido can have one because its PowerPoint add-in is the old kind (VBA plus a native library on the Mac, COM on Windows), which PowerPoint loads from a folder by design. This is an Office.js add-in, and Microsoft supports exactly two ways of installing one: Microsoft Marketplace, and an organisation's admin pushing it from the Microsoft 365 admin centre. Everything else is what Microsoft calls sideloading, "not for production".
So the installers automate the sideload, and that's all they do. They're the same as Font
Manager's (pptx-font-manager-addin), with the names changed:
| Mac | Windows | |
|---|---|---|
| File | Advanced-Exporter-for-PowerPoint.pkg | Advanced-Exporter-for-PowerPoint-Setup.exe |
| What it does | copies manifest.xml into ~/Library/Containers/com.microsoft.Powerpoint/Data/Documents/wef/ as stoatworks-advanced-exporter.xml | copies it to %LOCALAPPDATA%\Programs\Stoatworks\Advanced Exporter for PowerPoint\ and sets HKCU\Software\Microsoft\Office\16.0\Wef\Developer, value <add-in Id> = that path |
| Same as | Microsoft's office-addin-dev-settings on a Mac | the same tool on Windows (read from its 4.0.1 source); not the network-share catalog sideload-windows.ps1 sets up |
| Rights | your account only, no admin password | your account only, no UAC prompt |
| PowerPoint open? | Installer asks to quit it (must-close) | asks you to close it, then Retry |
| Prompts | macOS asks whether Installer may "access data from other apps": choose Allow | SmartScreen, below |
| Uninstall | Uninstall-Advanced-Exporter-for-PowerPoint.pkg | Settings ▸ Apps ▸ Installed apps |
| Signed | Developer ID Installer, notarised and stapled | no: SmartScreen will warn |
Both remove any other copy of the add-in (matched on its <Id>, so the sideload script's
pptx-exporter.manifest.xml goes, and Font Manager's file beside it doesn't) before adding
theirs, and the Mac one refuses politely if PowerPoint isn't installed or has never been opened
(its sandbox container, where wef lives, doesn't exist until then). scripts/sideload-mac.sh
does the same in reverse, so a dev copy never sits beside an installed one. Because the
manifest only points at the hosted pane, nobody needs to run an installer again unless
manifest.xml itself changes.
npm run installer:mac # sign + notarise from ~/.config/stoatworks/release-signing.env
npm run installer:mac:unsigned # quick local build
npm run installer:windows # needs makensis (brew install makensis)
What has been run, 2026-10-24, on macOS 26.4.1:
installer -pkg … -target CurrentUserHomeDirectory, no
password): install swapped the sideload script's copy for stoatworks-advanced-exporter.xml,
byte for byte the same manifest; Font Manager's manifest beside it was left alone; uninstall
removed it; a second uninstall said there was nothing to remove. Payload-free packages leave
no receipt. The installation check logged advanced-exporter: … container=true app=true to
/var/log/install.log.source=Notarized Developer ID). The copy that's installed on
this Mac now came from one of those, through installer.SystemPolicyAppData), and the
install waited on it until Allow was chosen; a grant from one run didn't carry over to the next.Two build traps, both found building Font Manager's:
LANG unset (or LC_ALL=C), Homebrew's 3.12 dies
with std::bad_alloc before reading a line. build-exe.sh sets one.._manifest.xml and ._postinstall. macOS 26 stamps every new file with
com.apple.provenance, xattr -c cannot remove it, and pkgbuild archives it as AppleDouble
whatever COPYFILE_DISABLE says. They're inert: the script only opens manifest.xml by name.manifest.xml the production manifest
taskpane.html the pane; index.html is the install page
src/taskpane.ts start-up, the deck, the format list, export
src/deck/ reading the .pptx: text, notes, hidden slides, transitions, links, media
src/host/ PowerPoint through Office.js, and a stand-in for browsers
src/render/ slide pictures (PowerPoint, or its PDF through pdf.js), sizing, canvas
src/formats/ one module per group of formats; types.ts is the contract
src/encode/ TIFF, BMP, TGA, GIF, WebP/AVIF (jSquash)
src/pdf/ pdf-lib helpers: Unicode text, bookmarks, links
src/output/ zipping and handing the file over
player/ the HTML5 presentation player (plain JS, copied into exports)
src/dev/ the shell-driven harness (development builds only)
src/deck/media.ts video and sound, through the font manager's scanner
vendor/pptx-font-manager/ that scanner and MEDIA.txt, via git subtree (npm run core:pull); don't edit
installer/mac/ the .pkg installer and uninstaller: postinstall scripts, distributions, pages
installer/windows/ the NSIS Setup.exe script, its build script and icon
fonts-src/ full Noto Sans; scripts/make-pdf-fonts.sh subsets it into src/assets/fonts
test/ vitest; fixtures/ are python-pptx decks; installer.test.ts runs the Mac scripts
PDFs are written with pdf-lib (MIT) and read with
pdf.js (Apache 2.0). WebP and AVIF use
jSquash (Apache 2.0), GIFs
gifenc (MIT), video
mp4-muxer and
webm-muxer (MIT), zips
fflate (MIT), and the reveal.js export
reveal.js (MIT). Video and sound are found and described by
pptx-font-manager's media scanner (MIT), vendored. PDF text is set in
Noto Sans (SIL Open Font Licence, src/assets/fonts/OFL.txt).
MIT licence.
This project is built on other people's work — see ATTRIBUTIONS.md.