Skip to content

Loading & Parsing ​

Loading turns raw .pptx, legacy .ppt, or pptx-viewer-json bytes into a fully resolved, typed PptxData object. All parsing happens in memory - no temporary files, no native code.

Construct a handler and load ​

ts
import { PptxHandler } from 'pptx-viewer-core';

const handler = new PptxHandler();
const data = await handler.load(arrayBuffer);

console.log(`${data.slides.length} slides loaded`);
console.log(`Canvas: ${data.width} x ${data.height}`);

handler.load(data, options?) accepts an ArrayBuffer and returns Promise<PptxData>. It recognizes OpenXML ZIP packages, legacy OLE2 PowerPoint files, and a JSON object carrying the "format": "pptx-viewer-json" marker.

Keep the handler

The handler holds the in-memory ZIP. Use the same handler instance to later save() or fetch media via getImageData() / getMediaArrayBuffer().

Getting an ArrayBuffer ​

The engine is environment-agnostic; you just need bytes.

ts
const buffer = await fetch('presentation.pptx').then((r) => r.arrayBuffer());
const data = await handler.load(buffer);
ts
const file = input.files[0]; // File from <input type="file">
const buffer = await file.arrayBuffer();
const data = await handler.load(buffer);
ts
import { readFile } from 'node:fs/promises';

const node = await readFile('presentation.pptx'); // Buffer
const buffer = node.buffer.slice(node.byteOffset, node.byteOffset + node.byteLength);
const data = await handler.load(buffer as ArrayBuffer);

What the load pipeline does ​

When you call load(), the runtime:

  1. Detects the file format. Portable JSON is validated and overlaid on a generated blank archive. Encrypted OpenXML OLE2/CFB files are decrypted first when a password is supplied, and legacy binary PowerPoint files are converted to the model.
  2. Opens the ZIP with JSZip and parses [Content_Types].xml and ppt/presentation.xml.
  3. Parses each slide master, its theme, colour map, and layouts.
  4. For each slide, parses the shape tree and resolves the layout → master → theme style chain (see /guide/architecture).
  5. Parses text with style inheritance, animations, transitions, and media relationships.
  6. Parses comments, document properties, and embedded fonts.

The result is a single PptxData object holding everything needed to render, edit, or convert the deck.

Portable deck JSON ​

PptxJsonConverter produces a versioned, self-contained pptx-viewer-json document. It carries the presentation model and binary model fields as tagged base64, so it can be transferred without the original archive. load() recognizes its format marker automatically and prepares a minimal archive so ordinary editing and save() continue to work.

ts
import { PptxHandler, PptxJsonConverter } from 'pptx-viewer-core';

const json = PptxJsonConverter.toJson(data, { pretty: true, generator: 'my-app' });
const imported = new PptxHandler();
const restored = await imported.load(new TextEncoder().encode(json).buffer);
const bytes = await imported.save(restored.slides); // valid .pptx bytes

The current format is version 1. Use PptxJsonConverter.parse() when you need validation without rebuilding PptxData, or fromJson() when you only need the model.

Load options ​

ts
const data = await handler.load(buffer, {
	password: 'secret', // decrypt an encrypted file (see below)
	allowExternalImages: false, // default false - http(s) image URLs are dropped
	maxUncompressedBytes: 500 * 1024 * 1024, // zip-bomb guard, 500 MiB default
});
OptionDefaultPurpose
password-Decrypts an encrypted package before parsing.
allowExternalImagesfalseWhen false, relationship targets resolving to http:///https:// are dropped from rendered slides (SSRF / privacy mitigation). Set true to allow them through.
maxUncompressedBytes500 MiBTotal uncompressed budget. Exceeding it (or 65,536 entries) rejects with ZipBombError.
eagerDecodeImagesfalseDecode embedded images during load rather than lazily.

Accessing slides, theme, and metadata ​

ts
const data = await handler.load(buffer);

// Slides
const first = data.slides[0];
console.log(first.id, first.elements.length, first.notes);

// Canvas / dimensions
console.log(data.width, data.height); // pixels

// Theme
console.log(data.theme?.name);
console.log(data.theme?.fontScheme?.majorFont?.latin);

// Document metadata
console.log(data.coreProperties?.title, data.coreProperties?.creator);

// Structure
console.log(data.sections, data.slideMasters, data.slideLayouts);

See /guide/data-model for the full shape of PptxData, PptxSlide, and friends.

Iterating elements and narrowing by type ​

Every slide's elements array is a list of PptxElement - a discriminated union of 16 variants. Always narrow with the type discriminant before touching variant-specific fields:

ts
for (const slide of data.slides) {
	for (const el of slide.elements) {
		switch (el.type) {
			case 'shape':
			case 'text':
				console.log('text:', el.text);
				break;
			case 'image':
				console.log('image at', el.imagePath);
				break;
			case 'table':
				console.log('table rows:', el.tableData?.rows.length);
				break;
			case 'chart':
				console.log('chart type:', el.chartData?.type);
				break;
			case 'group':
				// groups nest child elements recursively
				console.log('group children:', el.children.length);
				break;
		}
	}
}

Narrow before access

TypeScript only exposes variant fields (like imagePath or tableData) after you've narrowed on el.type. This is the intended pattern - see /guide/data-model.

Embedded media ​

To pull bytes for an embedded image or media file referenced by an element:

ts
const dataUrl = await handler.getImageData(element.imagePath); // base64 data URL
const bytes = await handler.getMediaArrayBuffer(mediaPath); // ArrayBuffer

Encrypted files ​

If the file is password-protected and you call load() without a password, the engine throws EncryptedFileError. Provide options.password to decrypt before parsing:

ts
const data = await handler.load(buffer, { password: 'secret' });

See /core/encryption for the full encryption and write-back API.

Released under the Apache-2.0 License.