Skip to content

Public API

Angular has no forwardRef imperative handle the way React does. Instead, PowerPointViewerComponent's programmatic API is just public methods on the component instance, reached through a template reference variable or Angular's viewChild() signal query.

ts
import { Component, viewChild } from '@angular/core';
import { PowerPointViewerComponent } from 'pptx-angular-viewer';

@Component({
	selector: 'app-editor',
	standalone: true,
	imports: [PowerPointViewerComponent],
	template: `
		<button (click)="save()">Save</button>
		<button (click)="viewer().goNext()">Next Slide</button>
		<button (click)="viewer().undo()">Undo</button>
		<pptx-viewer #viewer [content]="content" [canEdit]="true" />
	`,
})
export class EditorComponent {
	readonly viewer = viewChild.required(PowerPointViewerComponent);

	async save(): Promise<void> {
		const bytes = await this.viewer().getContent();
		// persist `bytes` (a Uint8Array)
	}
}

Template reference vs viewChild

#viewer in the template plus @ViewChild(PowerPointViewerComponent) viewer!: PowerPointViewerComponent works too (see the package README); viewChild() is the modern signal-based equivalent used above. Either way you get the same component instance and the same methods.

Contract shared across bindings

The methods below implement the same PowerPointViewerAPI contract (defined in pptx-viewer-shared) that React's PowerPointViewerHandle and Vue's defineExpose surface also implement - all three framework bindings expose an equivalent API surface, just through each framework's own idiom (React forwardRef handle, Vue defineExpose, Angular public methods).

ts
import type { PowerPointViewerAPI, ViewerMode } from 'pptx-angular-viewer';

Methods

Serialization

MethodSignatureDescription
getContent() => Promise<Uint8Array>Serialises the current document to .pptx bytes on demand. When editing, serialises the edited deck (templates merged back).
MethodSignatureDescription
goTo(index: number) => voidNavigate to a specific slide (zero-based). No-op when out of range.
goPrev() => voidNavigate to the previous slide.
goNext() => voidNavigate to the next slide.

Undo / Redo

MethodSignatureDescription
undo() => voidUndo the last editing action. No-op when nothing to undo.
redo() => voidRedo the last undone action.
canUndo() => booleanWhether an undo action is available.
canRedo() => booleanWhether a redo action is available.

Zoom

MethodSignatureDescription
getZoom() => numberGet the current zoom level (1 = 100%).
setZoom(level: number) => voidSet the zoom level (clamped to 0.2 - 3.0).
zoomIn() => voidZoom in by one step.
zoomOut() => voidZoom out by one step.
zoomReset() => voidReset zoom to 100%.

Mode

MethodSignatureDescription
getMode() => stringGet the current viewer mode: 'preview', 'edit', 'present', or 'master'.
setMode(mode: string) => voidSwitch mode programmatically. 'present' enters slideshow, 'master' enters template-edit mode, anything else returns to normal preview/edit.

Read-only state

MethodSignatureDescription
getActiveSlideIndex() => numberGet the zero-based active slide index.
setActiveSlideIndex(index: number) => voidSet the active slide (alias of goTo).
getSlideCount() => numberGet the total number of slides.
isDirty() => booleanWhether the document has unsaved changes.

Slide access

Slide methods return full PptxSlide objects from pptx-viewer-core with complete type information (elements, notes, transitions, animations, etc.).

MethodSignatureDescription
getSlides() => readonly PptxSlide[]Get all slides in the deck.
getSlide(index: number) => PptxSlide | undefinedGet a slide by zero-based index.
getActiveSlide() => PptxSlide | undefinedGet the currently active slide.

Slide manipulation

MethodSignatureDescription
addSlide(afterIndex?: number) => voidAdd a blank slide (after active by default).
deleteSlides(indexes: number[]) => voidDelete slides at indexes.
duplicateSlides(indexes: number[]) => voidDuplicate slides at indexes.
moveSlide(from: number, to: number) => voidMove a slide from one position to another.
toggleHideSlides(indexes: number[]) => voidToggle the hidden flag on slides.

Element access

Element methods return full PptxElement objects (discriminated union of text, shape, image, table, chart, connector, group, etc.) with complete type-specific properties.

MethodSignatureDescription
getElements(slideIndex?: number) => readonly PptxElement[]Get elements (active slide by default).
getElementById(elementId: string, slideIndex?: number) => PptxElement | undefinedGet element by ID.

Element manipulation

MethodSignatureDescription
updateElement(elementId: string, updates: Partial<PptxElement>) => voidPatch element properties.
deleteElements(elementIds: string[]) => voidDelete elements by ID.
duplicateElement(elementId: string) => string | undefinedDuplicate; returns new element ID.

Selection

MethodSignatureDescription
getSelectedElementIds() => string[]Get IDs of currently selected elements.
selectElements(ids: string[]) => voidProgrammatically select elements by ID.
clearSelection() => voidClear the current selection.

Example: external controls

ts
@Component({
	template: `
		<button (click)="viewer().goPrev()">Prev</button>
		<button (click)="viewer().goNext()">Next</button>
		<span>Slide {{ viewer().getActiveSlideIndex() + 1 }}</span>
		<span>{{ viewer().getActiveSlide()?.elements?.length }} elements</span>
		<button (click)="viewer().zoomIn()">Zoom In</button>
		<button (click)="viewer().zoomOut()">Zoom Out</button>
		<button (click)="viewer().undo()" [disabled]="!viewer().canUndo()">Undo</button>
		<button (click)="viewer().addSlide()">Add Slide</button>
		<pptx-viewer #ref [content]="content" [canEdit]="true" />
	`,
})
export class ToolbarComponent {
	readonly viewer = viewChild.required(PowerPointViewerComponent, {
		read: PowerPointViewerComponent,
	});
}

getContent vs contentChange

getContent() is a pull API: serialise on demand, e.g. when a Save button is clicked. contentChange is a push event that fires with fresh bytes as the document changes. Use whichever fits your save model; they return equivalent Uint8Array content.

Openable file kinds

The package root re-exports the shared answer to "can the viewer open this file?", so a host's drop target and its <input accept> cannot disagree with the loader. Hand-rolled endsWith chains drift: every demo in this repo once shipped .pptx,.ppt,.json, which refused on drop a .pptm that File > Open inside the viewer accepted without complaint.

ts
import {
	PPTX_OPEN_ACCEPT,
	PRESENTATION_OPEN_EXTENSIONS,
	isSupportedPresentationFile,
	isLegacyBinaryPresentation,
	presentationBaseName,
	savedPresentationFileName,
	type SavedPresentationFormat,
} from 'pptx-angular-viewer';
ExportTypeDescription
PPTX_OPEN_ACCEPTstringReady-made <input type="file" accept> value: .pptx,.ppsx,.pptm,.potx,.ppt,.json.
PRESENTATION_OPEN_EXTENSIONSreadonly string[]The same list unjoined, for a drop target that wants to test extensions itself.
isSupportedPresentationFile(name?: string | null) => booleanCheap pre-filter for a picked or dropped file name. Extension-only; the real answer is the loader's sniff.
isLegacyBinaryPresentation(name?: string | null) => booleanTrue for the binary PowerPoint 97-2003 family (.ppt / .pps / .pot), which the viewer reads but never writes.
presentationBaseName(name?: string | null, fallback?: string) => stringThe file-name stem, directories and any loadable extension removed (a path like decks/report.ppt becomes report).
savedPresentationFileName(name?: string | null, format?: SavedPresentationFormat) => stringThe name a saved copy should be offered under: report.ppt becomes report.pptx.
SavedPresentationFormat'pptx' | 'ppsx' | 'pptm'The formats the save path can produce. Binary .ppt is deliberately absent: output is always OpenXML.

savedPresentationFileName is the one that matters on Save As. Output is always an OpenXML package, so keeping a legacy source extension would hand the user a .ppt whose bytes are a ZIP, which PowerPoint refuses to open.

Released under the Apache-2.0 License.