How to Export OpenMAIC Content to PPTX and HTML Using `lib/export`

OpenMAIC's lib/export module provides two production-ready hooks—useExportPPTX and useExportClassroom—to generate editable PowerPoint decks and self-contained interactive HTML packages directly from your classroom scenes.

The export library in THU-MAIC/OpenMAIC transforms generated course content into portable, offline-ready formats. Whether you need a speaker-ready .pptx file or a fully interactive classroom experience bundled for distribution, the pipeline handles media resolution, asset inlining, and ZIP assembly automatically.

Export Format Overview

Format Primary Hook Builder Function Output Characteristics
PowerPoint (.pptx) useExportPPTX buildPptxBlob Editable slides with embedded media, shapes, charts, tables, LaTeX, video/audio, and speaker notes
Interactive HTML + Classroom ZIP useExportClassroom buildResourcePackZip Self-contained ZIP with inlined HTML pages, assets, and a manifest.json for re-import

Both formats are generated serverlessly in the browser using pptxgenjs for PPTX creation and native ZIP APIs for packaging.

Exporting to PowerPoint (PPTX)

How useExportPPTX Works

The hook gathers slide content from the stage store, builds a PPTX blob using pptxgenjs, and triggers a download. Here's the internal flow as implemented in [lib/export/use-export-pptx.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/use-export-pptx.ts):

1. Collect slides and scenes:

const slides = useStageStore(s => s.scenes.filter(s => s.content.type === 'slide')
                                         .map(s => (s.content as SlideContent).canvas));
const scenes = useStageStore(s => s.scenes);

Source: use-export-pptx.ts#L13-L15

2. Build the PPTX blob via buildPptxBlob:

  • Each slide canvas becomes a pptxgen slide with preserved layout and background
  • HTML text is converted to PPTX text properties using formatHTML
  • Media is resolved through resolvePptxEmbeddableSrc and embedded as Base64 data URLs
  • Speaker notes are assembled from speech actions via buildSpeakerNotes

Key implementation details:

3. Trigger download:

const blob = await buildPptxBlob(...);
saveAs(blob, `${fileName}.pptx`);

Source: use-export-pptx.ts#L144-L160

React Hook Usage

import { useExportPPTX } from '@/lib/export/use-export-pptx';

function ExportPPTXButton() {
  const { exporting, exportPPTX } = useExportPPTX();

  return (
    <button disabled={exporting} onClick={exportPPTX}>
      {exporting ? 'Exporting…' : 'Download PPTX'}
    </button>
  );
}

The exporting boolean indicates active processing, useful for UI loading states.

Exporting Interactive HTML (Classroom ZIP)

How useExportClassroom Works

The classroom export creates offline-ready interactive experiences from scenes marked with content.type === 'interactive'. The buildResourcePackZip function in [lib/export/use-export-pptx.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/use-export-pptx.ts#L223-L260) handles:

  • HTML asset inlining: External CSS, JavaScript, and images are fetched and embedded as data URIs via inlineHtmlAssets
  • Proxy-aware fetching: createProxiedFetch respects CSP and authentication requirements
  • Manifest generation: buildStageAssetManifest creates a manifest.json for later re-import
  • Media bundling: All audio, generated video, and image assets are included in the ZIP

React Hook Usage

import { useExportClassroom } from '@/lib/export/use-export-classroom';

function ExportHTMLButton() {
  const { exporting, exportClassroomZip } = useExportClassroom();

  return (
    <button disabled={exporting} onClick={exportClassroomZip}>
      {exporting ? 'Preparing…' : 'Download HTML Package'}
    </button>
  );
}

The resulting ZIP contains:

  • Inlined HTML pages for each interactive scene
  • Embedded media assets
  • manifest.json with stage metadata and scene definitions

Manual Builder Access (Advanced)

For testing, server-side usage, or custom orchestration, import the builder functions directly:

import { buildPptxBlob, buildResourcePackZip } from '@/lib/export/use-export-pptx';

// Build PPTX from prepared slide data
const pptxBlob = await buildPptxBlob(
  slides,           // Slide canvas data
  slideScenes,      // Scene metadata for slides
  viewportRatio,    // Aspect ratio (e.g., 16/9)
  viewportSize,     // { width: number, height: number }
  ratioPx2Inch,     // Pixel-to-inch conversion
  ratioPx2Pt,       // Pixel-to-point conversion
  stageId,          // Unique stage identifier
);

// Build complete classroom ZIP (includes PPTX + interactive HTML)
const zipResult = await buildResourcePackZip(
  scenes,           // All scenes (slides + interactive)
  slides,           // Slide canvas data
  slideScenes,      // Slide scene metadata
  {
    viewportRatio,
    viewportSize,
    ratioPx2Inch,
    ratioPx2Pt,
    fileName: 'my-course',
    getPptxBlob: () => pptxBlob,  // Lazy PPTX generator
  },
);

Key Export Library Files

File Purpose
[lib/export/use-export-pptx.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/use-export-pptx.ts) PPTX hook, blob builder, and resource-pack orchestrator
[lib/export/use-export-classroom.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/use-export-classroom.ts) Classroom ZIP hook and builder exposure
[lib/export/inline-assets.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/inline-assets.ts) CSS/JS/image inlining for offline HTML
[lib/export/proxied-fetch.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/proxied-fetch.ts) Authenticated, CSP-compliant fetch wrapper
[lib/export/svg2base64.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/svg2base64.ts) SVG-to-Base64 conversion for PPTX embedding
[lib/export/html-asset-inventory.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/html-asset-inventory.ts) HTML asset scanning and dependency detection
[lib/export/classroom-zip-types.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/classroom-zip-types.ts) TypeScript definitions for ZIP manifests
[lib/export/classroom-zip-utils.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/classroom-zip-utils.ts) Media collection and manifest utilities

Summary

  • Use useExportPPTX for editable PowerPoint decks with full media embedding and speaker notes
  • Use useExportClassroom for self-contained ZIP packages with offline-ready interactive HTML
  • Both hooks provide exporting state for UI feedback and handle all media resolution automatically
  • Builders like buildPptxBlob and buildResourcePackZip are exposed for advanced use cases
  • The lib/export module ensures all exported content works offline through aggressive asset inlining and Base64 embedding

Frequently Asked Questions

Does the PPTX export preserve animations and transitions?

No. The buildPptxBlob function captures static slide states including shapes, text formatting, images, and media placement. Complex canvas animations are rendered as their final frames. Speaker notes from speech actions are preserved as PPTX notes.

Can I customize the PPTX output dimensions or aspect ratio?

Yes. The buildPptxBlob function accepts viewportRatio, viewportSize, ratioPx2Inch, and ratioPx2Pt parameters that control slide dimensions and coordinate scaling. These map your canvas coordinates to PPTX inches and points.

What makes the HTML package "offline-ready"?

The inlineHtmlAssets function in [lib/export/inline-assets.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/inline-assets.ts) fetches all external CSS, JavaScript, font, and image references and replaces them with data URIs. Combined with Base64-embedded media, this produces HTML files with zero external dependencies.

How does createProxiedFetch handle authentication?

The proxied fetch in [lib/export/proxied-fetch.ts](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/export/proxied-fetch.ts) routes requests through your application's API layer. This automatically includes session cookies, bearer tokens, and other auth headers required to access protected media URLs, while respecting Content Security Policy restrictions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →