node-pptx-templater 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +28 -3
  2. package/README.md +175 -327
  3. package/package.json +12 -3
  4. package/src/cli/commands/build.js +30 -31
  5. package/src/cli/commands/debug.js +23 -23
  6. package/src/cli/commands/extract.js +21 -21
  7. package/src/cli/commands/inspect.js +23 -23
  8. package/src/cli/commands/validate.js +17 -17
  9. package/src/cli/index.js +39 -36
  10. package/src/core/OutputWriter.js +79 -78
  11. package/src/core/PPTXTemplater.js +856 -273
  12. package/src/core/TemplateEngine.js +67 -71
  13. package/src/core/ValidationEngine.js +246 -0
  14. package/src/index.js +30 -17
  15. package/src/managers/ChartManager.js +195 -70
  16. package/src/managers/ContentTypesManager.js +49 -45
  17. package/src/managers/HyperlinkManager.js +146 -142
  18. package/src/managers/ImageManager.js +336 -0
  19. package/src/managers/MediaManager.js +62 -81
  20. package/src/managers/RelationshipManager.js +99 -95
  21. package/src/managers/ShapeManager.js +340 -0
  22. package/src/managers/SlideManager.js +408 -311
  23. package/src/managers/TableManager.js +979 -262
  24. package/src/managers/TextManager.js +197 -0
  25. package/src/managers/ZipManager.js +69 -69
  26. package/src/managers/charts/ChartCacheGenerator.js +75 -58
  27. package/src/managers/charts/ChartParser.js +9 -13
  28. package/src/managers/charts/ChartRelationshipManager.js +12 -10
  29. package/src/managers/charts/ChartWorkbookUpdater.js +59 -56
  30. package/src/parsers/XMLParser.js +47 -50
  31. package/src/templates/blankPptx.js +3 -2
  32. package/src/templates/slideTemplate.js +28 -34
  33. package/src/utils/contentTypesHelper.js +40 -54
  34. package/src/utils/errors.js +18 -18
  35. package/src/utils/idUtils.js +16 -14
  36. package/src/utils/logger.js +18 -16
  37. package/src/utils/relationshipUtils.js +19 -20
  38. package/src/utils/xmlUtils.js +26 -26
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.3] - 2026-06-02
9
+
10
+ ### Added
11
+ - **Dynamic Formatting in updateTable**: Added support for inline cell styling (color fill `fill`, text alignment `align`, and `fontSize`) directly on cell objects passed to `updateTable`.
12
+ - **Comprehensive Tailwind Site**: Overhauled doc builder script to generate a premium Tailwind CSS documentation portal with clientside search, clipboard copying, sitemap.xml, robots.txt, and Schema.org metadata.
13
+
14
+ ### Fixed
15
+ - **XML Element Ordering**: Enforced strict schema-valid element sequence (`a:pPr` -> runs -> `a:endParaRPr`) in slide table cell paragraphs. This resolves the bug where split cells inheriting from template merged cells had their text runs ignored by PowerPoint's XML compiler.
16
+ - **Template Style Inheritance**: Fixed a bug in `updateTable` where cloned rows always copied the first data row (`trs[1]`). The engine now correctly inherits formatting, alignment, and fill styles from matching indices in the template (`trs[i]`) when available.
17
+
18
+ ## [1.0.2] - 2026-06-02
19
+
20
+ ### Added
21
+ - **Table Cell Merging & Unmerging Engine**: Fully implemented horizontal cell spans (`gridSpan`, `hMerge`), vertical cell spans (`rowSpan`, `vMerge`), and rectangular block merges.
22
+ - **PowerPoint Repair Protection**: Implemented unique 32-bit unsigned `rowId` generation inside `<a16:rowId>` XML tags for all cloned and inserted rows, eliminating PowerPoint's "Repair Mode" error prompts.
23
+ - **Merge Integrations**: Integrated template-driven merges (`merge` configs array and cell-level `colSpan`/`rowSpan`) inside the main `updateTable` orchestrator.
24
+ - **Integration Test Suite**: Added a comprehensive merge test script under `tests/integration/PPTXMerge.test.js`.
25
+
26
+ ## [1.0.1] - 2026-05-19
27
+
28
+ ### Changed
29
+ - **CommonJS Target Conversion**: Converted the source code modules compilation and packaging layout from pure ES Modules (ESM) to CommonJS (CJS) to ensure compatibility with standard Node.js deployment, packaging, and edge runtime environments.
30
+
8
31
  ## [1.0.0] - 2026-05-17
9
32
 
10
33
  ### Added
@@ -16,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
39
  - `ChartManager` — direct chart XML data updates (bar, line, pie, area, scatter)
17
40
  - `TableManager` — table row replacement preserving all formatting
18
41
  - `HyperlinkManager` — external URL and slide-to-slide hyperlink injection
19
- - `MediaManager` — image embedding with SHA-1 content deduplication
42
+ - `MediaManager` — image embedding with SHA-1 deduplication
20
43
  - `TemplateEngine` — `{{placeholder}}` replacement with fragmented run normalization
21
44
  - `OutputWriter` — file, buffer, and stream output
22
45
  - CLI: `build`, `validate`, `inspect`, `extract`, `debug` commands
@@ -29,11 +52,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
29
52
  - MIT License
30
53
 
31
54
  ### Architecture
32
- - Pure JavaScript ES Modules (no TypeScript)
33
55
  - Zero PPTX generation library dependencies
34
56
  - Only uses: `jszip`, `fast-xml-parser`, `fs-extra`, `commander`, `chalk`, `ora`
35
57
  - Async/await throughout
36
58
  - Private class fields (`#field`) for encapsulation
37
59
  - Modular architecture following SOLID principles
38
60
 
39
- [1.0.0]: https://github.com/jsuyog2/pptx-templater/releases/tag/v1.0.0
61
+ [1.0.3]: https://github.com/jsuyog2/node-pptx-templater/compare/v1.0.2...v1.0.3
62
+ [1.0.2]: https://github.com/jsuyog2/node-pptx-templater/compare/v1.0.1...v1.0.2
63
+ [1.0.1]: https://github.com/jsuyog2/node-pptx-templater/compare/v1.0.0...v1.0.1
64
+ [1.0.0]: https://github.com/jsuyog2/node-pptx-templater/releases/tag/v1.0.0
package/README.md CHANGED
@@ -1,31 +1,38 @@
1
1
  # node-pptx-templater
2
2
 
3
- > A low-level PowerPoint OpenXML templating engine for Node.js that generates and edits PPTX files directly through XML manipulation without relying on PowerPoint generation libraries.
3
+ > High-performance, low-level PowerPoint (PPTX) OpenXML template engine for Node.js. Dynamically replace text, insert images, update charts (with Excel workbook data caching), and merge table cells without PowerPoint corruption or Repair Mode prompts.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/node-pptx-templater.svg)](https://www.npmjs.com/package/node-pptx-templater)
6
- [![CI](https://github.com/jsuyog2/node-pptx-templater/actions/workflows/ci.yml/badge.svg)](https://github.com/jsuyog2/node-pptx-templater/actions/workflows/ci.yml)
7
- [![Coverage](https://img.shields.io/codecov/c/github/jsuyog2/node-pptx-templater)](https://codecov.io/gh/jsuyog2/node-pptx-templater)
8
- [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)
9
- [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org)
10
- [![ES Modules](https://img.shields.io/badge/ESM-only-blueviolet)](https://nodejs.org/api/esm.html)
5
+ [![npm version](https://img.shields.io/npm/v/node-pptx-templater.svg?style=flat-square&color=blue)](https://www.npmjs.com/package/node-pptx-templater)
6
+ [![CI Build Status](https://img.shields.io/github/actions/workflow/status/jsuyog2/node-pptx-templater/ci.yml?branch=main&style=flat-square)](https://github.com/jsuyog2/node-pptx-templater/actions/workflows/ci.yml)
7
+ [![Bundle Size](https://img.shields.io/bundlephobia/min/node-pptx-templater?style=flat-square&color=brightgreen)](https://bundlephobia.com/package/node-pptx-templater)
8
+ [![Downloads](https://img.shields.io/npm/dm/node-pptx-templater.svg?style=flat-square&color=orange)](https://www.npmjs.com/package/node-pptx-templater)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](./LICENSE)
10
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?style=flat-square)](https://nodejs.org)
11
+
12
+ ---
13
+
14
+ ## ⚡ Why node-pptx-templater?
15
+
16
+ Traditional PowerPoint generation libraries require building slides from scratch in code, which is verbose, hard to maintain, and strips away the power of visual design tools.
17
+
18
+ `node-pptx-templater` takes a different approach: **Design visually in PowerPoint, populate dynamically in Node.js.**
19
+
20
+ You create slide decks using PowerPoint, Google Slides, or Keynote, set your formatting, themes, animations, and layouts, and place placeholders like `{{company}}` or `{{revenue-chart}}`. `node-pptx-templater` parses the template and updates text, injects images, replaces chart values (updating both Excel workbook data caches and XML shapes), and merges tables dynamically while keeping the presentation 100% compliant with standard OpenXML guidelines.
11
21
 
12
22
  ---
13
23
 
14
24
  ## ✨ Features
15
25
 
16
- | Feature | Description |
17
- |---|---|
18
- | 🏗️ **Zero PPTX library dependencies** | Direct OpenXML/ZIP manipulation only |
19
- | 🔁 **Text replacement** | Handles fragmented runs (`{{placeholders}}`) |
20
- | 📊 **Chart updates** | Bar, Line, Pie, Area, Scatter data only, style preserved |
21
- | 📋 **Table updates** | Replace rows while preserving all formatting |
22
- | 🔗 **Hyperlinks** | External URLs, shape links, slide-to-slide navigation |
23
- | **Add new slides** | Text, images, shapes with auto-generated XML |
24
- | 🎯 **Slide selection** | By number, ID, or custom tags |
25
- | 📤 **Multiple outputs** | `saveToFile()`, `toBuffer()`, `toStream()` |
26
- | 🔍 **Validation** | Structure validation with error reporting |
27
- | 🛠️ **CLI** | `build`, `validate`, `inspect`, `extract`, `debug` |
28
- | ⚡ **Performance** | Lazy loading, media deduplication, async/await |
26
+ - 🏗️ **Zero Native Office/Java Dependencies**: Runs on pure Javascript/Node.js, making it ideal for high-throughput cloud environments, Lambda, or serverless runtimes.
27
+ - 🔁 **Fragmented Placeholder Resolution**: PowerPoint often splits text runs like `{{company}}` into `<a:r>` nodes. Our engine merges and resolves fragmented tags automatically.
28
+ - 📊 **Full Chart Engine Integration**: Supports Bar, Column, Line, Pie, Doughnut, Area, Scatter, and Bubble charts. Automatically synchronizes chart XML properties and coordinates with the embedded Excel sheets (`ppt/embeddings/`).
29
+ - 📋 **Flexible Table Merging & Templating**:
30
+ - Horizontal column merge (`gridSpan` & `hMerge`), vertical row merge (`rowSpan` & `vMerge`), and rectangular block merges.
31
+ - Formats cells dynamically with inline options (`align`, `fontSize`, `fill`).
32
+ - Automatically handles slide table duplicates by generating unique `<a16:rowId>` 32-bit hashes to **prevent PowerPoint Repair Mode** screens.
33
+ - 🎨 **Shape & Image Manipulation**: Find shapes, clone layout blocks with offsets, replace image sources while keeping exact positions, or delete elements.
34
+ - 🎯 **Slide Management Operations**: Duplicate, reorder, delete, and import slides from external templates with automatic media asset deduplication.
35
+ - 🔍 **Deep Packaging Integrity Validation**: Real-time checking of relationships, XML schemas, table column numbers, and override duplicates.
29
36
 
30
37
  ---
31
38
 
@@ -35,372 +42,213 @@
35
42
  npm install node-pptx-templater
36
43
  ```
37
44
 
38
- **Requirements:** Node.js ≥ 18.0.0, ES Modules (`"type": "module"`)
39
-
40
45
  ---
41
46
 
42
47
  ## 🚀 Quick Start
43
48
 
44
- ```js
45
- import { PPTXTemplater } from 'node-pptx-templater';
46
-
47
- // Load a template PPTX
48
- const ppt = await PPTXTemplater.load('template.pptx');
49
-
50
- // Select slide(s) to work on (omit to work on all)
51
- ppt.useSlide(1);
49
+ Get up and running in under 60 seconds with this simple template rendering example:
52
50
 
53
- // Replace {{placeholder}} text
54
- ppt.replaceText({
55
- '{{title}}': 'Quarterly Report',
56
- '{{year}}': '2026',
57
- '{{company}}': 'Acme Corp',
58
- });
59
-
60
- // Update chart data
61
- ppt.updateChart('sales-chart', {
62
- categories: ['Jan', 'Feb', 'Mar'],
63
- series: [{ name: 'Revenue', values: [120, 150, 180] }],
64
- });
65
-
66
- // Update table rows
67
- ppt.updateTable('employees-table', [
68
- ['Name', 'Role', 'Department'],
69
- ['Alice', 'Engineer', 'Platform'],
70
- ['Bob', 'Designer', 'Product'],
71
- ]);
72
-
73
- // Save output
74
- await ppt.saveToFile('./output/report.pptx');
51
+ ```js
52
+ const { PPTXTemplater } = require('node-pptx-templater');
53
+
54
+ async function main() {
55
+ // 1. Load your PowerPoint presentation template
56
+ const ppt = await PPTXTemplater.load('monthly_report_template.pptx');
57
+
58
+ // 2. Select slide 1 and execute operations
59
+ ppt.useSlide(1)
60
+ .replaceTextByTag('title', 'Quarterly Earnings Report')
61
+ .replaceMultiple({
62
+ company: 'Acme Corporation',
63
+ year: '2026'
64
+ });
65
+
66
+ // 3. Update chart series data on Slide 2
67
+ ppt.useSlide(2)
68
+ .updateChartData('sales-chart', {
69
+ categories: ['Q1', 'Q2', 'Q3', 'Q4'],
70
+ series: [
71
+ { name: 'Target', values: [100, 120, 140, 160] },
72
+ { name: 'Revenue', values: [105, 118, 145, 172] }
73
+ ]
74
+ });
75
+
76
+ // 4. Update table with cell merging and formatting on Slide 3
77
+ ppt.useSlide(3)
78
+ .updateTable('sales-table', [
79
+ ['Region', 'Q1 Actual', 'Q2 Actual', 'Status'],
80
+ ['North', '120k', '140k', { value: 'On Track', align: 'ctr', fill: '10b981' }],
81
+ ['South', '95k', '110k', { value: 'Review', align: 'ctr', fill: 'f59e0b' }]
82
+ ]);
83
+
84
+ // 5. Save the non-corrupted PPTX back to disk
85
+ await ppt.saveToFile('./output/annual_earnings.pptx');
86
+ }
75
87
 
76
- // Or get a Buffer (for HTTP responses, emails, etc.)
77
- const buffer = await ppt.toBuffer();
88
+ main().catch(err => console.error(err));
78
89
  ```
79
90
 
80
91
  ---
81
92
 
82
- ## 📚 API Reference
83
-
84
- ### `PPTXTemplater`
85
-
86
- #### Static Methods
87
-
88
- | Method | Description |
89
- |---|---|
90
- | `PPTXTemplater.load(source)` | Load from file path or Buffer |
91
- | `PPTXTemplater.create()` | Create a blank presentation |
92
-
93
- #### Slide Selection
94
-
95
- | Method | Description |
96
- |---|---|
97
- | `.useSlide(...refs)` | Select slides by number/tag to apply operations |
98
- | `.useAllSlides()` | Reset to all slides |
99
- | `.tagSlide(num, tag)` | Assign custom tag for later selection |
100
-
101
- #### Content Manipulation
93
+ ## 🏗️ OpenXML Architecture & Internals
102
94
 
103
- | Method | Description |
104
- |---|---|
105
- | `.replaceText(replacements)` | Replace `{{key}}` placeholders |
106
- | `.updateChart(chartId, data)` | Update chart categories/series/values |
107
- | `.updateTable(tableId, rows)` | Replace table row data |
108
- | `.addHyperlink(options)` | Add/replace external hyperlink on text |
109
- | `.linkSlideNumber(options)` | Make slide reference navigate to another slide |
95
+ A `.pptx` file is an OPC (Open Packaging Convention) ZIP archive containing structured XML documents and asset folders:
110
96
 
111
- #### Slide Management
97
+ - `[Content_Types].xml` – Global manifest declaring content MIME types for every file part in the ZIP.
98
+ - `_rels/.rels` – Root-level package relationship index.
99
+ - `ppt/presentation.xml` – Root presentation settings and slide inventory (`sldIdLst`).
100
+ - `ppt/slides/slideN.xml` – Main slide canvas storing shapes, lines, tables, text runs, and layout components.
101
+ - `ppt/slides/_rels/slideN.xml.rels` – Relationship indexes mapping slide XML components to charts, layouts, and image assets.
112
102
 
113
- | Method | Description |
114
- |---|---|
115
- | `.addSlide(options)` | Add a new slide with elements |
116
- | `.cloneSlide(num, atPos?)` | Duplicate an existing slide |
117
- | `.removeSlide(num)` | Delete a slide |
118
- | `.reorderSlides(order)` | Reorder slides |
119
- | `.exportSlides(...nums)` | Export subset to new engine |
120
-
121
- #### Output
122
-
123
- | Method | Description |
124
- |---|---|
125
- | `.saveToFile(path)` | Write PPTX to disk |
126
- | `.toBuffer()` | Get PPTX as Node.js Buffer |
127
- | `.toStream()` | Get PPTX as readable stream |
128
-
129
- #### Utilities
130
-
131
- | Method | Description |
132
- |---|---|
133
- | `.getInfo()` | Presentation metadata |
134
- | `.validate()` | Structure validation |
135
- | `.slideCount` | Total slide count (getter) |
103
+ ### Preventing PowerPoint Table Repair Errors
104
+ PowerPoint slide tables utilize unique 32-bit identifiers inside `<a16:rowId>` nodes for collaborative edits. Duplicating rows using naive array copy operations results in overlapping IDs, triggering Microsoft PowerPoint's **"PowerPoint found a problem with content"** repair screen on open.
105
+ `node-pptx-templater` intercepts all table operations (adding, cloning, inserting, or merging rows) and dynamically injects newly generated unique `rowId` hashes, ensuring a seamless, warning-free loading experience in:
106
+ - Microsoft PowerPoint (Desktop, Mac, Online)
107
+ - Google Slides
108
+ - LibreOffice Impress
136
109
 
137
110
  ---
138
111
 
139
- ## 🏗️ Architecture
140
-
141
- ```
142
- node-pptx-templater/
143
- ├── PPTXTemplater ← Main orchestrator / public API
144
- │ ├── ZipManager ← ZIP archive read/write (JSZip)
145
- │ ├── XMLParser ← XML parse/build (fast-xml-parser)
146
- │ ├── RelationshipManager ← .rels file management
147
- │ ├── SlideManager ← Slide discovery, ordering, CRUD
148
- │ ├── ChartManager ← Chart XML data updates
149
- │ ├── TableManager ← Table row replacement
150
- │ ├── HyperlinkManager ← Hyperlink injection
151
- │ ├── MediaManager ← Image embedding + deduplication
152
- │ ├── TemplateEngine ← {{placeholder}} replacement
153
- │ └── OutputWriter ← File/Buffer/Stream output
154
- ```
112
+ ## 📊 Feature Comparison Matrix
155
113
 
156
- ### OpenXML PPTX Structure
114
+ | Feature / Library | `node-pptx-templater` | `pptxgenjs` | `pptx-template` | `pptx-automizer` | `officegen` |
115
+ |:---|:---:|:---:|:---:|:---:|:---:|
116
+ | **Approach** | **Template-based** | Code-based | Template-based | Template-based | Code-based |
117
+ | **No PPTX Corruption / Repair Warnings** | **Yes** (Automatic Metadata Sync) | Yes | No (Fragile row duplication) | Yes | Yes (Limited layouts) |
118
+ | **Text Run Fragmentation Resolution** | **Yes** (Dynamic merging) | N/A | No (Placeholder breaks) | Yes | N/A |
119
+ | **Chart Data Workbook Sync** | **Yes** (Direct excel caching) | Yes | No (Only raw XML text) | Yes | Yes |
120
+ | **Horizontal & Vertical Cell Merge** | **Yes** (gridSpan, rowSpan, hMerge, vMerge) | Yes | No | No | No |
121
+ | **Slide Duplication & Reordering** | **Yes** | No | No | Yes | No |
122
+ | **External Slide Imports** | **Yes** (With asset deduplication) | No | No | Yes | No |
123
+ | **Dependencies** | **Zero Native Dependencies** | Zero | Zero | Zero | Node-zip, xmlbuilder |
157
124
 
158
- A `.pptx` file is a ZIP archive (Open Packaging Convention) containing XML files:
125
+ ---
159
126
 
160
- ```
161
- presentation.pptx (ZIP)
162
- ├── [Content_Types].xml # MIME types for all parts
163
- ├── _rels/.rels # Root relationships
164
- ├── ppt/
165
- │ ├── presentation.xml # Slide list, master references
166
- │ ├── _rels/presentation.xml.rels
167
- │ ├── slides/
168
- │ │ ├── slide1.xml # Slide content XML
169
- │ │ ├── slide2.xml
170
- │ │ └── _rels/slide1.xml.rels
171
- │ ├── slideLayouts/ # Layout templates
172
- │ ├── slideMasters/ # Master slide designs
173
- │ ├── theme/ # Color & font themes
174
- │ ├── charts/ # Embedded chart XML
175
- │ └── media/ # Images, videos
176
- └── docProps/
177
- ├── core.xml # Title, author, dates
178
- └── app.xml # App metadata
179
- ```
127
+ ## 📚 API Reference
180
128
 
181
- ### Relationship Flow
129
+ ### Slide Operations
182
130
 
131
+ #### `duplicateSlide(slideIndex, atPosition)`
132
+ Duplicates a slide.
133
+ ```js
134
+ ppt.duplicateSlide(1, 2); // Duplicate Slide 1 and insert it at position 2
183
135
  ```
184
- presentation.xml
185
- └─[rId2]──► slides/slide1.xml
186
- └─[rId1]──► slideLayouts/slideLayout1.xml
187
- └─[rId2]──► charts/chart1.xml
188
- └─ (chart data XML)
189
- └─[rId3]──► media/image1.png
190
- └─[rId4]──► https://example.com (external)
191
- ```
192
-
193
- ### Text Fragmentation Problem & Solution
194
-
195
- PowerPoint sometimes splits `{{placeholder}}` across multiple XML text runs:
196
136
 
197
- ```xml
198
- <!-- What you write in PowerPoint: -->
199
- {{title}}
200
-
201
- <!-- What the XML actually contains: -->
202
- <a:r><a:t>{{ti</a:t></a:r>
203
- <a:r><a:t>tle}}</a:t></a:r>
137
+ #### `deleteSlide(slideIndex)`
138
+ Deletes a slide from the deck.
139
+ ```js
140
+ ppt.deleteSlide(3); // Delete Slide 3
204
141
  ```
205
142
 
206
- **Our solution:** The `TemplateEngine` normalizes runs within each paragraph by:
207
- 1. Concatenating all run text content
208
- 2. Detecting placeholders in the combined text
209
- 3. Merging affected runs into one (preserving the first run's formatting)
210
- 4. Injecting the replacement value
211
-
212
- ---
213
-
214
- ## 🖥️ CLI Usage
215
-
216
- ```bash
217
- # Install globally
218
- npm install -g node-pptx-templater
219
-
220
- # Build a PPTX from template + JSON data
221
- node-pptx-templater build template.pptx output.pptx --data data.json
222
-
223
- # Validate a PPTX structure
224
- node-pptx-templater validate presentation.pptx
225
-
226
- # Inspect internal structure
227
- node-pptx-templater inspect presentation.pptx --all
228
-
229
- # Extract a slide's XML
230
- node-pptx-templater extract presentation.pptx --slide 1 --out slide1.xml
231
-
232
- # Debug a corrupted PPTX
233
- node-pptx-templater debug broken.pptx --fix --out repaired.pptx
143
+ #### `moveSlide(fromIndex, toIndex)`
144
+ Moves a slide to a new position.
145
+ ```js
146
+ ppt.moveSlide(1, 3); // Move Slide 1 to position 3
234
147
  ```
235
148
 
236
- ### Data JSON format for `build` command
237
-
238
- ```json
239
- {
240
- "text": {
241
- "{{title}}": "Annual Report 2026",
242
- "{{company}}": "Acme Corp",
243
- "{{date}}": "January 2026"
244
- },
245
- "charts": {
246
- "sales-chart": {
247
- "categories": ["Q1", "Q2", "Q3", "Q4"],
248
- "series": [
249
- { "name": "Revenue", "values": [145, 210, 190, 250] }
250
- ]
251
- }
252
- },
253
- "tables": {
254
- "data-table": [
255
- ["Name", "Role", "Dept"],
256
- ["Alice", "Engineer", "Platform"]
257
- ]
258
- }
259
- }
149
+ #### `importSlideFrom(sourcePresentation, sourceSlideIndex)`
150
+ Deep-copies a slide from another loaded presentation, automatically remapping layouts, shapes, charts, and deduplicating media assets.
151
+ ```js
152
+ const source = await PPTXTemplater.load('marketing_slides.pptx');
153
+ await ppt.importSlideFrom(source, 2); // Import Slide 2 of marketing deck
260
154
  ```
261
155
 
262
156
  ---
263
157
 
264
- ## 📊 Supported Chart Types
265
-
266
- | OpenXML Element | Chart Type |
267
- |---|---|
268
- | `c:barChart` | Bar / Column |
269
- | `c:lineChart` | Line |
270
- | `c:pieChart` | Pie |
271
- | `c:areaChart` | Area |
272
- | `c:scatterChart` | Scatter / XY |
273
- | `c:doughnutChart` | Doughnut |
274
- | `c:radarChart` | Radar / Spider |
275
- | `c:bubbleChart` | Bubble |
276
-
277
- ---
278
-
279
- ## ⚡ Performance
280
-
281
- | Operation | Benchmark (avg) |
282
- |---|---|
283
- | Load 50-slide PPTX | ~120ms |
284
- | Text replacement (20 placeholders) | ~2ms |
285
- | Buffer generation | ~80ms |
286
- | Chart update | ~5ms |
287
- | Table update | ~3ms |
288
-
289
- > Run your own: `npm run benchmark`
290
-
291
- ---
292
-
293
- ## 🐛 Troubleshooting
158
+ ### Table Manipulation
294
159
 
295
- ### Placeholders not being replaced
296
-
297
- If `{{placeholder}}` is not replaced, the text is likely fragmented across runs.
298
- Use the `PPTX_LOG_LEVEL=debug` environment variable to see detailed logs:
299
-
300
- ```bash
301
- PPTX_LOG_LEVEL=debug node your-script.js
160
+ #### `updateTable(tableId, data)`
161
+ Updates a table with rows data, merge rules, and cell styles.
162
+ ```js
163
+ ppt.updateTable('revenue-table', [
164
+ ['Year', 'Revenue', 'Profit'],
165
+ ['2025', '120k', '40k'],
166
+ ['2026', '150k', { value: '60k', fill: '10b981', align: 'ctr' }]
167
+ ]);
302
168
  ```
303
169
 
304
- Extract the slide XML to inspect:
305
- ```bash
306
- node-pptx-templater extract template.pptx --slide 1 --out slide1.xml
170
+ #### `mergeCells(options)`
171
+ Merges a rectangular block of cells. Supports horizontal, vertical, and block merging, concatenating all text from the merged region into the top-left cell.
172
+ ```js
173
+ ppt.mergeCells({
174
+ tableId: 'sales-table',
175
+ startRow: 1,
176
+ startCol: 1,
177
+ endRow: 2,
178
+ endCol: 2
179
+ });
307
180
  ```
308
181
 
309
- Look for `<a:t>` elements and check if the placeholder is split.
310
-
311
- ### Chart not updating
312
-
313
- Chart names must match the shape's `cNvPr name` attribute exactly.
314
- Use `--inspect --charts` to see all chart names:
315
-
316
- ```bash
317
- node-pptx-templater inspect template.pptx --charts
182
+ #### `unmergeCells(options)`
183
+ Splits a merged region back to its original individual cells, removing `gridSpan`, `rowSpan`, `hMerge`, and `vMerge` attributes.
184
+ ```js
185
+ ppt.unmergeCells({
186
+ tableId: 'sales-table',
187
+ row: 1,
188
+ col: 1
189
+ });
318
190
  ```
319
191
 
320
- ### Generated PPTX fails to open
192
+ ---
321
193
 
322
- Run the debug command to check for structural issues:
194
+ ### Chart Integration
323
195
 
324
- ```bash
325
- node-pptx-templater debug output.pptx
196
+ #### `updateChartData(chartId, data)`
197
+ Overwrites chart categories and series values. Updates the embedded Excel spreadsheet to ensure the chart matches perfectly on refresh.
198
+ ```js
199
+ ppt.updateChartData('sales-chart', {
200
+ categories: ['Q1', 'Q2', 'Q3', 'Q4'],
201
+ series: [
202
+ { name: 'Revenue', values: [100, 150, 180, 220] }
203
+ ]
204
+ });
326
205
  ```
327
206
 
328
- Common causes:
329
- - Missing content type entries for new slides
330
- - Broken relationship IDs
331
- - Invalid XML characters in replacement values
332
-
333
- ### File is corrupted
334
-
335
- ```bash
336
- node-pptx-templater debug corrupted.pptx --fix --out repaired.pptx
207
+ #### `updateChartTitle(chartId, title)`
208
+ ```js
209
+ ppt.updateChartTitle('sales-chart', 'Revenue Growth (2026)');
337
210
  ```
338
211
 
339
- The debug command attempts:
340
- - Removing invalid XML control characters
341
- - Fixing unescaped `&` in text content
342
- - Repairing broken relationship IDs
343
-
344
212
  ---
345
213
 
346
- ## 🔌 Plugin System
347
-
348
- Extend the engine by subclassing `PPTXTemplater`:
214
+ ## Performance Benchmarks
349
215
 
350
- ```js
351
- import { PPTXTemplater } from 'pptx-templater';
216
+ Tested on a standard 50-slide enterprise presentation template:
352
217
 
353
- class MyEngine extends PPTXTemplater {
354
- /**
355
- * Custom method: fills a slide from a data object.
356
- */
357
- async fillFromData(slideNum, data) {
358
- this.useSlide(slideNum);
218
+ | Operation | Execution Duration |
219
+ |:---|:---|
220
+ | Load PPTX Template | ~110ms |
221
+ | Find & Replace 20 Text Placeholders | ~2.5ms |
222
+ | XML Schema & Integrity Validation Check | ~14ms |
223
+ | Dynamic Row Insertion & Merging (15 rows) | ~3ms |
224
+ | Save and Re-package to PPTX ZIP | ~78ms |
359
225
 
360
- const textReplacements = {};
361
- for (const [key, val] of Object.entries(data.text || {})) {
362
- textReplacements[`{{${key}}}`] = String(val);
363
- }
226
+ ---
364
227
 
365
- this.replaceText(textReplacements);
228
+ ## ❓ FAQ & Troubleshooting
366
229
 
367
- if (data.chart) {
368
- this.updateChart(data.chart.id, data.chart);
369
- }
230
+ ### PowerPoint displays a "Repair" prompt when opening my generated file
231
+ This is commonly caused by:
232
+ 1. **Missing overridden content type**: A new slide or chart XML was added but not registered in `[Content_Types].xml`.
233
+ 2. **Duplicate row identifiers**: If table rows are duplicated without generating a new unique `rowId` under `<a16:rowId>`.
234
+ 3. **Invalid relationship mapping**: An asset (like an image or worksheet) is referenced in slide XML but is missing from the slide's `.rels` file.
370
235
 
371
- return this;
372
- }
373
- }
236
+ *Fix*: Ensure you always use the public `saveToFile()` or `toBuffer()` helper functions, which automatically execute structural verification passes and update relationship chains.
374
237
 
375
- // Usage
376
- const ppt = await MyEngine.load('template.pptx');
377
- await ppt.fillFromData(1, {
378
- text: { title: 'My Report', date: '2026-01-01' },
379
- chart: { id: 'sales', categories: ['Q1'], series: [{ name: 'Rev', values: [100] }] },
380
- });
381
- await ppt.saveToFile('output.pptx');
238
+ ### My text placeholders are not replacing
239
+ PowerPoint text editors segment formatting runs into separate XML elements. The text `{{title}}` may look normal in PowerPoint, but in XML it could be split into `<a:t>{{ti</a:t><a:t>tle}}</a:t>`.
240
+ *Fix*: You can enable logger output to see split tags:
241
+ ```bash
242
+ PPTX_LOG_LEVEL=debug node app.js
382
243
  ```
383
-
384
- ---
385
-
386
- ## 🛣️ Roadmap
387
-
388
- - [ ] SmartArt data update
389
- - [ ] Speaker notes modification
390
- - [ ] Slide transitions and animation metadata editing
391
- - [ ] PPTX → HTML export (read-only)
392
- - [ ] Password-protected PPTX support
393
- - [ ] Native chart creation from scratch (without template)
394
- - [ ] Watch mode for development
395
- - [ ] Browser/WASM support (via jszip already)
244
+ To fix this in PowerPoint, highlight the entire placeholder block, cut it, and paste it back as "Keep Text Only" to unify the XML text runs.
396
245
 
397
246
  ---
398
247
 
399
248
  ## 🤝 Contributing
400
249
 
401
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
250
+ We welcome contributions! Please check out [CONTRIBUTING.md](./CONTRIBUTING.md) to get started.
402
251
 
403
- Quick steps:
404
252
  ```bash
405
253
  git clone https://github.com/jsuyog2/node-pptx-templater.git
406
254
  cd node-pptx-templater
@@ -412,4 +260,4 @@ npm test
412
260
 
413
261
  ## 📄 License
414
262
 
415
- MIT see [LICENSE](./LICENSE)
263
+ Licensed under the MIT License. © [node-pptx-templater contributors](./LICENSE)