pptx-automizer

repository·main·Indexed 42 days ago

https://github.com/singerla/pptx-automizer

A Node.js-based template engine for automating the manipulation and generation of PowerPoint (.pptx) files. It allows developers to merge templates, customize slide content via XML callbacks, and modify native tables, charts, and text. The tool uses a queuing system where operations like .addSlide() and .modifyElement() are staged and then executed via .write(), .stream(), or .getJSZip().

Tokens
45.4K
Snippets
120
Records
173
Agent score
50%

What's inside pptx-automizer

  1. Introduction to pptx-automizer

    main

    pptx-automizer is a Node.js-based PowerPoint (.pptx) generator designed to automate the manipulation of existing .pptx files. Instead of building slides from scratch, it uses a template-based approach where you can import, merge, and customize existing templates.

    Key Features

    • Template-Driven: Use your own library of well-designed .pptx files as templates. Any existing slide or element can serve as a data-driven template.
    • Content Modification: Most content can be modified using callbacks with xmldom.
    • Dynamic Content: For creating elements from scratch, it wraps PptxGenJS to allow adding dynamic content to your existing templates.
    • Deferred Execution: A core concept is that methods like addSlide() and modifyElement() only queue work. No changes are applied until you call an execution method like write(), stream(), or getJSZip().
  2. Security and Dependency Changes (PR #202)

    main

    As of August 2026, pptx-automizer has replaced the extract-zip and image-size dependencies with internal implementations to resolve high-severity security vulnerabilities (CVE-2026-19693 and CVE-2025-71329/CVE-2025-71330).

    Key Changes

    • Zip Extraction: Replaced extract-zip with extractToFolder (located in src/helper/jszip-helper.ts). This implementation is built on jszip and includes protections against absolute paths and zip-slip attacks. It rejects absolute paths and symlink entries.
    • Image Dimension Parsing: Replaced image-size with a custom parser in src/helper/image-dimensions.ts. This parser is designed to be loop-safe and supports PNG, JPEG, GIF, BMP, WebP, and SVG.

    Important Limitations

    • Memory Usage in fs-mode: The new extractToFolder implementation reads the entire archive into memory. While extract-zip previously streamed from disk, the current implementation may consume more memory when processing large .pptx files in fs-mode.
    • Unsupported Formats: The internal image parser does not currently support TIFF or ICO formats. If these are encountered, the system will fall back to a default dimension of 100x100 and log a warning.
  3. Limitations on modifying existing elements

    main
    The library is currently limited to adding content to an output presentation. It cannot directly modify a specific existing element on a slide while leaving the rest of the slide untouched. To achieve a modification effect, you must include all other slides in your process (e.g., by looping through the slides of a presentation).
  4. How pptx-automizer works: The Template-Based Mental Model

    main

    Core Workflow

    pptx-automizer is a template-based engine for Node.js (server-side only). You do not build slides from a blank canvas. Instead, follow this workflow:

    1. Design in PowerPoint: Create your slides in PowerPoint and save them as .pptx files.
    2. Name your shapes: For any shape you want to automate (text, images, charts), give it a unique, readable name using PowerPoint's Selection pane (ALT+F10, then rename with F2).
    3. Load Templates: Load a root template (which defines the master slides, theme, and size) and any number of source templates (which provide the content slides).
    4. Queue Modifications: Use addSlide to bring slides from source templates into the root, and use callbacks to modify elements (e.g., setting text, feeding chart data, or swapping images).
    5. Execute: Call write(), stream(), or getJSZip() to execute the queued work and generate the file.

    Key Constraints

    • Server-side only: Designed for Node.js environments.
    • No blank canvases: Always start with a template. If no template exists, use the PptxGenJS bridge to generate shapes from scratch.
    • One instance, one output: Use one Automizer instance per presentation build. If you need multiple output files, create a fresh new Automizer(...) for each.
  5. Template and Archive Layer Abstractions

    main

    The library distinguishes between source and output templates to provide type safety and clarity:

    • SourceTemplate: Represents the original .pptx file you are loading.
    • OutputTemplate: Represents the modified presentation being generated.
    • Template.import: This is the factory method used to load a template. It returns a union of PresTemplate or RootPresTemplate based on the input.

    When working with archives, the library uses an idempotent ensureOpen() mechanism. This ensures that any method requiring a loaded archive (like write, folder, or output) automatically handles the initialization of the underlying archive structure.

  6. Understand the Deferred Execution Model

    main

    A core concept of pptx-automizer is its deferred execution model. Instead of applying changes immediately to a file, modifiers typically queue up operations or work on an in-memory representation. Changes are finalized when a write operation (like write()) is called.

    Important Note on Errors: Since Phase 1, callback errors are not swallowed; they will cause the write() operation to reject. Always ensure your modifier callbacks are robust to prevent failing the entire write process.

  7. How pptx-automizer works: The Queuing Concept

    main

    The most important mental model in pptx-automizer is that operations are queued, not executed immediately.

    Methods such as .addSlide() and .modifyElement() do not perform any file manipulation when called; instead, they add tasks to a work queue. This queue includes all modification callbacks you provide. The actual processing and file generation only occur when you call an execution method like .write(), .stream(), or .getJSZip(). This ensures that all modifications are applied in the correct order to the presentation.

  8. Understand the Modification contract for chart modifiers

    main

    When using chart modifiers, the Modification type controls how XML elements are targeted and created. Understanding these two fields is critical to avoid silent failures or incorrect XML generation:

    1. index: This is positional over existing siblings. It refers to the index of the element among its current siblings. Because assertElement can only grow a collection by exactly one clone per call, you must walk indices in order (0, 1, 2...) if you are adding multiple elements.
    2. isRequired: When set to false, the library will modify the element if it exists, but will never create it if it is absent. This is useful for applying styles to existing data labels without accidentally fabricating new ones in a template that shouldn't have them.

    To target specific data points by their actual category index (rather than their position in the XML), use matchIdx which resolves elements by matching the child c:idx value.

  9. Understand limitations and requirements

    main

    Environment

    • Requires a Node.js environment (server-side only).

    Supported Content

    • Shapes: Most types (including connection shapes, tables, and charts) are supported. Hyperlinks, video, and audio may have issues.
    • Charts: Native charts are supported. Extended types (waterfall, map) work but may require additional modifiers for extended properties.
    • Tables: Must be native tables. Grouped-shape 'fake tables' cannot be used with setTable.
    • Data: Chart datasheets must have the data table starting at cell A:1 in the template.

    Unsupported/Limited Features

    • Animations: Currently out of scope. Adding/removing shapes may break existing animations because id attributes are not synchronized.
    • Slide Layouts: Individual layouts can be imported but cannot be added, modified, or removed directly. Layouts should not contain complex content like charts or images.
    • Direct Manipulation: The library is primarily for adding content. To modify a specific element in an existing slide while leaving others untouched, you must include all other slides in the process.
  10. Ensure PPTX validity with package invariants

    main

    The library automatically runs package invariants on every written archive to catch common corruption classes like dangling relationships. These checks ensure that the generated file is structurally sound and won't cause errors in PowerPoint.

    Key invariants checked:

    • All r:id, r:embed, and r:link references resolve to valid entries in the part's _rels file.
    • All relationship targets resolve to existing parts in the archive (no orphaned media/charts).
    • Every part is correctly covered in [Content_Types].xml.
    • The slide list in ppt/presentation.xml is consistent with actual slide<n>.xml parts.

    If a test fails due to an invariant violation, it indicates a structural corruption. If the violation is a known issue (like stale relationship entries during content copying), it is reported as a knownIssue rather than a hard error.

  11. How 1-based numbering works for slides

    main

    Slide indexing in pptx-automizer is 1-based. When using addSlide(label, index), the index refers to the slide file number inside the source template, which may not correspond to its final position in the generated deck.

    Templates can be addressed by their filename or by a custom label provided during the .load() call.

    // Example: Taking the first slide from a template labeled 'shapes'
    addSlide('shapes', 1);
  12. How deferred execution works in pptx-automizer

    main
    In pptx-automizer, all operations like load(), addSlide(), and various modification methods are queued. Nothing is actually applied to the presentation structure or written to a file until the .write() method is invoked. This allows you to build up a complex sequence of presentation modifications before performing the heavy lifting of file generation.