tinyweb-office-slides
v0.1.0
Published
Open-source Node.js/TypeScript library for creating, reading, and editing PowerPoint (.pptx) presentations
Maintainers
Readme
tinyweb-office-slides
Open-source Node.js/TypeScript library for creating, reading, and editing PowerPoint (.pptx) presentations.
Features
- ✅ Create/Read PPTX files — full round-trip fidelity (preserves unmodified XML)
- ✅ Slides management — add, clone, remove, reorder, hide slides
- ✅ Shapes — rectangles, ellipses, arrows, callouts, connectors, group shapes (180+ preset types)
- ✅ Text formatting — bold, italic, underline, strikethrough, font size, font color, font family
- ✅ Fill formatting — solid, gradient, pattern, picture fills with color management (RGB, scheme, preset)
- ✅ Line formatting — width, dash style, arrowheads, cap/join styles
- ✅ Tables — rows, columns, cells with margins, spans, borders, fill
- ✅ 3D formatting — bevel, camera presets, light rig, material, extrusion
- ✅ Effects — blur, glow, outer/inner shadow, reflection, soft edge, preset shadow
- ✅ Images — add PNG/JPG/GIF images to slides
- ✅ Comments — slide comments with authors, positions, timestamps
- ✅ Document properties — title, author, subject, custom properties
- ✅ Notes slides — add/remove speaker notes
- ✅ Slide layouts & masters — layout management and theme integration
- ✅ TypeScript-first — full type declarations included
- ✅ Zero native dependencies — pure JavaScript, works everywhere Node.js runs
Installation
npm install tinyweb-office-slidesRequires Node.js >= 18.
Quick Start
Create a Presentation and Save
import { Presentation, ShapeType, FillType, NullableBool, Color } from 'tinyweb-office-slides';
// Create a new presentation
const pres = new Presentation();
// Access the first slide (created by default)
const slide = pres.slides[0];
// Add a shape
const shape = slide.shapes.addAutoShape(ShapeType.RECTANGLE, 50, 50, 200, 100);
// Set fill
shape.fillFormat.fillType = FillType.SOLID;
shape.fillFormat.solidFillColor.color = Color.fromArgb(255, 0, 70, 127);
// Set text
const textFrame = shape.addTextFrame('Hello, World!');
const portion = textFrame.paragraphs[0].portions[0];
const fmt = portion.portionFormat;
fmt.fontHeight = 24;
fmt.fontBold = NullableBool.TRUE;
fmt.fillFormat.solidFillColor.color = Color.white;
// Save to file
pres.save('output.pptx');
pres.dispose();Open and Modify an Existing File
import { Presentation, ShapeType, FillType } from 'tinyweb-office-slides';
const pres = new Presentation('input.pptx');
// Iterate through slides
for (let i = 0; i < pres.slides.length; i++) {
const slide = pres.slides[i];
console.log(`Slide ${i}: ${slide.name}`);
}
// Add a new slide
const layout = pres.layoutSlides[0];
const newSlide = pres.slides.addEmptySlide(layout);
// Add a shape to the new slide
newSlide.shapes.addAutoShape(ShapeType.ELLIPSE, 100, 100, 300, 200);
// Clone a slide
const clone = pres.slides.addClone(pres.slides[0]);
pres.save('modified.pptx');
pres.dispose();API Reference
Presentation
The main entry point for creating and manipulating PowerPoint files.
const pres = new Presentation(); // Create new
const pres = new Presentation('file.pptx'); // Open existing
// Properties
pres.slides // ISlideCollection
pres.layoutSlides // IGlobalLayoutSlideCollection
pres.masters // IMasterSlideCollection
pres.images // IImageCollection
pres.commentAuthors // ICommentAuthorCollection
pres.documentProperties // IDocumentProperties
pres.firstSlideNumber // Number (default: 1)
pres.currentDateTime // Date
pres.sourceFormat // SourceFormat
// Save
pres.save('output.pptx');
pres.dispose();Slide & SlideCollection
const slides = pres.slides;
// Add/remove slides
slides.addEmptySlide(layout); // Add from layout
slides.addClone(sourceSlide); // Clone existing
slides.removeAt(index); // Remove by index
slides.addClone(slides[0]); // Duplicate first slide
// Slide properties
const slide = slides[0];
slide.name = 'My Slide';
slide.hidden = true; // Hide in slideshow
slide.layoutSlide; // Layout reference
slide.notesSlideManager; // Speaker notes
slide.shapes; // Shape collectionShapes
const shapes = slide.shapes;
// Add shapes
shapes.addAutoShape(ShapeType.RECTANGLE, x, y, width, height);
shapes.addAutoShape(ShapeType.ELLIPSE, x, y, width, height);
shapes.addAutoShape(ShapeType.RIGHT_ARROW, x, y, width, height);
shapes.addConnector(ShapeType.BENT_CONNECTOR3, x, y, width, height);
shapes.addGroupShape();
shapes.addPictureFrame(ShapeType.RECTANGLE, x, y, w, h, image);
shapes.addTable(x, y, columnWidths, rowHeights);
// Shape properties
const shape = shapes[0];
shape.x = 100; // Position (points)
shape.y = 200;
shape.width = 300;
shape.height = 150;
shape.rotation = 45; // Degrees
shape.name = 'My Shape';
shape.hidden = false;
shape.alternativeText = 'Description';
// Shape formatting
shape.fillFormat // FillFormat
shape.lineFormat // LineFormat
shape.effectFormat // EffectFormat
shape.threeDFormat // ThreeDFormat
// Remove
shapes.remove(shape);
shapes.removeAt(0);
shapes.clear();Text Formatting
const shape = slide.shapes.addAutoShape(ShapeType.RECTANGLE, 10, 10, 200, 50);
const textFrame = shape.addTextFrame('Hello World');
// Paragraph level
const para = textFrame.paragraphs[0];
para.paragraphFormat.alignment = TextAlignment.CENTER;
para.paragraphFormat.spaceBefore = 5;
para.paragraphFormat.spaceAfter = 5;
// Portion (text run) level
const portion = para.portions[0];
const fmt = portion.portionFormat;
fmt.fontHeight = 24; // Points
fmt.fontBold = NullableBool.TRUE;
fmt.fontItalic = NullableBool.TRUE;
fmt.fontUnderline = TextUnderlineType.SINGLE;
fmt.strikethroughType = TextStrikethroughType.NONE;
// Font color
fmt.fillFormat.fillType = FillType.SOLID;
fmt.fillFormat.solidFillColor.color = Color.fromArgb(255, 70, 127);FillFormat
// Solid fill
shape.fillFormat.fillType = FillType.SOLID;
shape.fillFormat.solidFillColor.color = Color.red;
// Gradient fill
shape.fillFormat.fillType = FillType.GRADIENT;
const grad = shape.fillFormat.gradientFormat;
grad.gradientDirection = GradientDirection.FROM_CORNER1;
grad.gradientStops.add(0, Color.red);
grad.gradientStops.add(1, Color.blue);
// Pattern fill
shape.fillFormat.fillType = FillType.PATTERN;
shape.fillFormat.patternFormat.patternStyle = PatternStyle.DIAGONAL_CROSS;
// No fill
shape.fillFormat.fillType = FillType.NO_FILL;LineFormat
const lf = shape.lineFormat;
lf.width = 2.5; // Points
lf.dashStyle = LineDashStyle.DASH_DOT;
lf.capStyle = LineCapStyle.ROUND;
lf.joinStyle = LineJoinStyle.MITER;
// Arrowheads
lf.beginArrowheadStyle = LineArrowheadStyle.TRIANGLE;
lf.endArrowheadStyle = LineArrowheadStyle.OPEN;
lf.endArrowheadWidth = LineArrowheadWidth.MEDIUM;
lf.endArrowheadLength = LineArrowheadLength.LONG;
// Line color
lf.fillFormat.fillType = FillType.SOLID;
lf.fillFormat.solidFillColor.color = Color.red;Tables
const colWidths = [120.0, 120.0, 120.0];
const rowHeights = [40.0, 40.0];
const table = slide.shapes.addTable(50, 50, colWidths, rowHeights);
// Set cell text
table.rows[0][0].textFrame.text = 'Header 1';
table.rows[0][1].textFrame.text = 'Header 2';
table.rows[1][0].textFrame.text = 'Data 1';
// Cell margins
const cell = table.rows[0][0] as ICell;
cell.marginLeft = 5;
cell.marginTop = 3;
// Column width
table.columns[0].width = 150;Effects
// Outer shadow
shape.effectFormat.enableOuterShadowEffect();
const shadow = shape.effectFormat.outerShadowEffect;
shadow.blurRadius = 10;
shadow.distance = 5;
shadow.direction = 45;
// Glow
const glow = shape.effectFormat.glowEffect;
glow.radius = 8;
// Soft edge
shape.effectFormat.softEdgeEffect.radius = 5;3D Formatting
// Bevel
const td = shape.threeDFormat;
td.bevelTop.bevelType = BevelPresetType.CIRCLE;
td.bevelTop.width = 6;
td.bevelTop.height = 6;
// Camera
td.camera.cameraType = CameraPresetType.PERSPECTIVE_FRONT;
// Light rig
td.lightRig.rigType = LightRigPresetType.THREE_POINT;
td.lightRig.direction = LightingDirection.TOP;
// Material
td.material = MaterialPresetType.METAL;Images
import * as fs from 'fs';
const imageData = fs.readFileSync('photo.png');
const ppImage = pres.images.addImage(imageData);
slide.shapes.addPictureFrame(ShapeType.RECTANGLE, 50, 50, 200, 200, ppImage);Comments
import { PointF } from 'tinyweb-office-slides';
// Add author
const author = pres.commentAuthors.addAuthor('Jane Smith', 'JS');
// Add comment
const position = new PointF(10, 10);
author.comments.addComment('Review this', slide, position, new Date());
// Remove comment
author.comments.clear();Document Properties
pres.documentProperties.title = 'Quarterly Report';
pres.documentProperties.author = 'Finance Team';
pres.documentProperties.subject = 'Q4 2024';
pres.documentProperties.setCustomPropertyValue('Version', 3);
pres.documentProperties.setCustomPropertyValue('Approved', true);Notes Slides
const notes = slide.notesSlideManager.addNotesSlide();
notes.notesTextFrame.text = 'Speaker notes here...';
slide.notesSlideManager.removeNotesSlide();Shape Types (180+ presets)
Basic shapes, arrows, callouts, flowcharts, stars, banners, buttons, math symbols, connectors, and more.
| Category | Examples |
|----------|----------|
| Basic | RECTANGLE, ELLIPSE, TRIANGLE, DIAMOND, PENTAGON, HEXAGON |
| Arrows | RIGHT_ARROW, LEFT_ARROW, UP_ARROW, DOWN_ARROW, BENT_ARROW |
| Stars | FIVE_POINTED_STAR, SIX_POINTED_STAR, EIGHT_POINTED_STAR |
| Callouts | CALLOUT1, CALLOUT_CLOUD, CALLOUT_WEDGE_ELLIPSE |
| Flowchart | PROCESS_FLOW, DECISION_FLOW, DOCUMENT_FLOW |
| Connectors | STRAIGHT_CONNECTOR1, BENT_CONNECTOR2-5, CURVED_CONNECTOR2-5 |
TypeScript
Full TypeScript declarations are included. All classes, interfaces, enums, and types are exported:
import {
Presentation,
Slide,
SlideCollection,
AutoShape,
Connector,
GroupShape,
PictureFrame,
Table,
ShapeType,
FillType,
NullableBool,
Color,
PointF,
Size,
SizeF,
TextFrame,
Paragraph,
Portion,
PortionFormat,
FillFormat,
LineFormat,
ColorFormat,
EffectFormat,
ThreeDFormat,
ShapeBevel,
Camera,
LightRig,
FontData,
Fonts,
PPImage,
ImageCollection,
Comment,
CommentAuthor,
DocumentProperties,
NotesSlideManager,
SaveFormat,
// ... and more
} from 'tinyweb-office-slides';Dependencies
| Package | Purpose | |---------|---------| | jszip | PPTX ZIP container read/write | | fast-xml-parser | OOXML XML parsing and generation |
No native/binary dependencies — works on any platform where Node.js runs.
