pptx-builder-js
v1.1.2
Published
A TypeScript library for building PowerPoint (.pptx) files with template support and chart embedding
Maintainers
Readme
PPTX Builder JS
A powerful TypeScript library for creating PowerPoint (.pptx) presentations programmatically. Build professional presentations with charts, tables, shapes, images, and rich text formatting without relying on existing PPTX libraries.
✨ Features
- 🎯 Full TypeScript Support - Strong typing and IntelliSense support
- 📊 Rich Chart Support - Column, Line, Pie, Bar, Area, and Scatter charts with advanced styling
- 📈 Embedded Excel Data - Charts include properly embedded Excel workbooks
- 📋 Advanced Table Support - Professional tables with rich styling, borders, and formatting
- 🎨 Rich Text Formatting - Bold, italic, underline, colors, and font customization
- 🔷 Shape Support - Rectangles, circles, triangles, and lines
- 🖼️ Image Embedding - Support for PNG, JPEG, GIF, and BMP images
- 📋 Template Loading - Load and modify existing PowerPoint templates
- 🎨 Theme & Color Support - Built-in themes and extensive color palette
- 🧪 Comprehensive Testing - Full test suite with high coverage
- 🚀 Easy API - Intuitive, fluent API design
🚀 Installation
# Using pnpm (recommended)
pnpm add pptx-builder-js
# Using npm
npm install pptx-builder-js
# Using yarn
yarn add pptx-builder-js📖 Quick Start
import { PowerPointBuilder, THEME_COLORS, TableRow } from "pptx-builder-js";
// Create a new presentation
const pptx = new PowerPointBuilder({
title: "My Presentation",
author: "John Doe",
subject: "Demo Presentation",
});
// Add a slide
const slide = pptx.addSlide("Welcome Slide");
// Add text
slide.addText(
"Hello, World!",
{ x: 100, y: 100 },
{ width: 400, height: 50 },
{ fontSize: 24, bold: true, color: "#0066CC" }
);
// Add a chart
const chartData = {
categories: ["Q1", "Q2", "Q3", "Q4"],
series: [
{
name: "Sales",
values: [100, 150, 200, 175],
color: THEME_COLORS.ACCENT_1,
},
],
title: "Quarterly Sales",
};
slide.addChart(
"column",
{ x: 50, y: 200 },
{ width: 500, height: 300 },
chartData
);
// Add a table
slide.addTable(
[
{
cells: [
{ content: "Product" },
{ content: "Sales" },
{ content: "Growth" },
],
style: {
fill: THEME_COLORS.ACCENT_1,
font: { bold: true, color: THEME_COLORS.LIGHT_1 },
borders: {
all: {
show: true,
color: "#333",
width: 2,
style: "solid",
},
},
},
},
{
cells: [
{ content: "Product A" },
{ content: "$100K" },
{
content: "+15%",
style: { font: { color: "#22C55E", bold: true } },
},
],
},
],
{ x: 50, y: 350 },
{ width: 400, height: 100 }
);
// Save the presentation
await pptx.saveToFile("my-presentation.pptx");📋 Table API
Basic Table Creation
import { TableRow } from "pptx-builder-js";
const tableData: TableRow[] = [
{
// Header row
cells: [
{ content: "Name" },
{ content: "Position" },
{ content: "Salary" },
],
style: {
fill: "#4F46E5",
font: { bold: true, color: "#FFFFFF" },
textAlign: "center",
},
},
{
// Data row
cells: [
{ content: "John Doe" },
{ content: "Engineer" },
{ content: "$75,000" },
],
},
];
slide.addTable(tableData, { x: 50, y: 100 }, { width: 500, height: 150 });Advanced Table Styling
Simplified Border API
// Set borders for all edges at once
const simpleTable: TableRow[] = [
{
cells: [
{
content: "All Red Borders",
style: {
borders: {
all: {
show: true,
color: "#FF0000",
width: 3,
style: "solid",
},
},
},
},
],
},
];
// Mix 'all' with individual edge overrides
const mixedBorders: TableRow[] = [
{
cells: [
{
content: "Blue base, Red top",
style: {
borders: {
all: {
show: true,
color: "#0000FF",
width: 1,
style: "solid",
},
top: {
show: true,
color: "#FF0000",
width: 4,
style: "solid",
},
},
},
},
],
},
];
// No borders (clean modern look)
const noBorders: TableRow[] = [
{
cells: [
{
content: "Clean look",
style: {
borders: { all: { show: false } },
},
},
],
},
];Priority-Based Styling
const advancedTable: TableRow[] = [
{
cells: [{ content: "Product" }, { content: "Q1 Sales" }],
style: {
// Row-level styling
fill: "#F3F4F6",
font: { bold: true },
borders: {
all: { show: true, color: "#6B7280", width: 1, style: "solid" },
},
},
},
{
cells: [
{ content: "Widget A" },
{
content: "$25,000",
style: {
// Cell-level styling (highest priority)
fill: "#DCFCE7",
font: { color: "#22C55E", bold: true },
borders: {
all: {
show: true,
color: "#22C55E",
width: 2,
style: "solid",
},
},
},
},
],
},
];
slide.addTable(
advancedTable,
{ x: 50, y: 100 },
{ width: 400, height: 100 },
{
// Table-level styling (lowest priority)
style: {
globalBorders: {
all: { show: true, color: "#E5E7EB", width: 1, style: "solid" },
},
padding: { top: 10, bottom: 10, left: 12, right: 12 },
font: { family: "Arial", size: 11 },
},
}
);Column-Specific Styling
slide.addTable(
tableData,
{ x: 50, y: 100 },
{ width: 600, height: 200 },
{
columns: [
{
style: {
fill: "#F3F4F6",
textAlign: "left",
font: { bold: true },
},
}, // Name column
{ style: { fill: "#EFF6FF", textAlign: "center" } }, // Position column
{
style: {
fill: "#ECFDF5",
textAlign: "right",
font: { family: "Courier New" },
},
}, // Salary column
],
style: {
globalBorders: {
all: { show: true, color: "#D1D5DB", width: 1, style: "solid" },
},
},
}
);Table Style Priority Order
The table styling system follows a clear priority hierarchy:
- Cell-specific styles (highest priority)
- Row-level styles
- Column-level styles
- Special row/column styles (header, footer)
- Table default styles
- Global table styles (lowest priority)
📊 Chart API
Supported Chart Types
- Column Charts - Vertical bar charts for comparing categories
- Line Charts - Show trends over time or categories
- Pie Charts - Display proportions of a whole
- Bar Charts - Horizontal bar charts
- Area Charts - Line charts with filled areas
- Scatter Charts - Show relationships between two variables
Basic Chart Creation
import { ChartData, THEME_COLORS } from "pptx-builder-js";
const chartData: ChartData = {
categories: ["Q1", "Q2", "Q3", "Q4"],
series: [
{
name: "Revenue",
values: [25000, 32000, 28000, 35000],
color: THEME_COLORS.ACCENT_1,
},
{
name: "Expenses",
values: [18000, 22000, 20000, 25000],
color: THEME_COLORS.ACCENT_2,
},
],
title: "Quarterly Performance",
xAxisTitle: "Quarter",
yAxisTitle: "Amount ($)",
};
slide.addChart(
"column",
{ x: 50, y: 120 },
{ width: 650, height: 400 },
chartData
);Comprehensive Chart Styling
const styledChart: ChartData = {
categories: ["Product A", "Product B", "Product C"],
series: [
{
name: "Sales",
values: [1500000, 1200000, 1800000],
color: THEME_COLORS.ACCENT_1,
},
],
title: "Product Sales Analysis",
xAxisTitle: "Products",
yAxisTitle: "Sales ($)",
style: {
// Chart title styling
title: {
font: { family: "Calibri", size: 18, bold: true },
color: THEME_COLORS.DARK_1,
},
// X-axis comprehensive styling
xAxis: {
title: {
font: { family: "Calibri", size: 12, bold: true },
color: THEME_COLORS.DARK_1,
},
labels: {
font: { family: "Calibri", size: 10 },
color: THEME_COLORS.DARK_2,
rotation: -45, // Rotate labels
},
line: { show: true, color: THEME_COLORS.DARK_2, width: 1 },
tickMarks: {
major: { show: true, type: "out" },
minor: { show: false },
},
},
// Y-axis with number formatting and scaling
yAxis: {
title: {
font: { family: "Calibri", size: 12, bold: true },
color: THEME_COLORS.DARK_1,
},
labels: {
font: { family: "Calibri", size: 10 },
color: THEME_COLORS.DARK_2,
numberFormat: {
type: "currency",
currencySymbol: "$",
useThousandsSeparator: true,
decimalPlaces: 0,
},
},
scale: {
min: 0,
max: 2000000,
majorUnit: 500000,
},
tickMarks: {
major: { show: true, type: "out" },
minor: { show: true, type: "in" },
},
},
// Grid lines
gridLines: {
major: {
show: true,
color: Colors.variants.lighter80(THEME_COLORS.DARK_2),
width: 0.5,
style: "solid",
},
minor: {
show: false,
},
},
// Legend styling
legend: {
show: true,
position: "top",
font: { family: "Calibri", size: 10 },
color: THEME_COLORS.DARK_1,
},
// Data labels
dataLabels: {
show: true,
position: "outsideEnd",
font: { family: "Calibri", size: 9, bold: true },
color: THEME_COLORS.DARK_1,
numberFormat: {
type: "custom",
customFormat: '#,##0,"K"', // Thousands with K suffix
},
},
// Chart and plot area styling
chartArea: {
fill: THEME_COLORS.LIGHT_1,
border: { color: THEME_COLORS.DARK_2, width: 1, style: "solid" },
},
plotArea: {
fill: "#FFFFFF",
border: { color: THEME_COLORS.LIGHT_2, width: 0.5, style: "solid" },
},
},
};Number Format Types
// Currency formatting
numberFormat: {
type: "currency",
currencySymbol: "$",
useThousandsSeparator: true,
decimalPlaces: 2,
}
// Result: $1,234.56
// Percentage formatting
numberFormat: {
type: "percentage",
decimalPlaces: 1,
}
// Result: 15.3%
// Custom formatting
numberFormat: {
type: "custom",
customFormat: "#,##0.0,,\"M\"", // Millions with M suffix
}
// Result: 1.2M
// Scientific notation
numberFormat: {
type: "scientific",
decimalPlaces: 2,
}
// Result: 1.23E+06Advanced Color Control
import { Colors, COLOR_PALETTES, HEX_COLORS } from "pptx-builder-js";
// Individual column colors
const chartWithCustomColors: ChartData = {
categories: ["Q1", "Q2", "Q3", "Q4"],
series: [
{
name: "Sales",
values: [30000, 45000, 35000, 50000],
pointColors: [
"#FF0000", // Q1 - Red
THEME_COLORS.ACCENT_2, // Q2 - Theme color
Colors.rgb(0, 255, 0), // Q3 - Green (RGB)
Colors.lighter(THEME_COLORS.ACCENT_1, 0.4), // Q4 - Light accent
],
},
],
title: "Sales by Quarter",
};
// Using color palettes
const paletteChart: ChartData = {
categories: ["A", "B", "C", "D", "E", "F"],
series: [
{
name: "Revenue",
values: [120, 98, 150, 87, 134, 92],
pointColors: COLOR_PALETTES.BUSINESS, // Professional colors
},
],
title: "Product Revenue",
};🎨 Text and Formatting
Rich Text Formatting
slide.addText(
"Styled Text Example",
{ x: 50, y: 100 },
{ width: 400, height: 50 },
{
fontSize: 24,
bold: true,
italic: false,
underline: true,
color: "#0066FF", // Blue hex color
fontFamily: "Arial",
textAlign: "center",
verticalAlign: "middle",
}
);Color System
Built-in Color Types
import {
Colors,
THEME_COLORS,
HEX_COLORS,
COLOR_PALETTES,
} from "pptx-builder-js";
// RGB Colors (Color objects) - using rgb() function
Colors.rgb(255, 0, 0); // Red: "#FF0000"
Colors.rgb(0, 0, 255); // Blue: "#0000FF"
Colors.rgb(0, 255, 0); // Green: "#00FF00"
Colors.rgb(255, 128, 0); // Custom RGB: "#FF8000"
// Hex Colors
("#FF0000"); // Direct hex string
HEX_COLORS.RED; // "#FF0000"
HEX_COLORS.BLUE; // "#0000FF"
// Theme Colors with Variants
THEME_COLORS.ACCENT_1; // Primary theme color
THEME_COLORS.ACCENT_2; // Secondary theme color
THEME_COLORS.DARK_1; // Dark theme color
THEME_COLORS.LIGHT_1; // Light theme color
// Color Variants
Colors.lighter(THEME_COLORS.ACCENT_1, 0.4); // 40% lighter
Colors.darker(THEME_COLORS.ACCENT_1, 0.3); // 30% darker
Colors.theme("accent2", 0.5); // Accent2 with 50% tintColor Utility Functions
// RGB to Hex conversion
const orangeColor = Colors.rgb(255, 165, 0); // Returns "#FFA500"
// Theme color creation
const lightAccent = Colors.theme("accent1", 0.6); // 60% lighter
const darkAccent = Colors.theme("accent1", -0.4); // 40% darker
// Quick theme helpers
const lightAccent2 = Colors.accent1(0.5); // Accent1 50% lighter
const darkAccent3 = Colors.accent2(-0.3); // Accent2 30% darkerColor Palettes
// Professional business colors
COLOR_PALETTES.BUSINESS; // [accent1, accent2, accent3, ...]
// Bright, eye-catching colors
COLOR_PALETTES.VIBRANT; // ["#FF6B6B", "#4ECDC4", "#45B7D1", ...]
// Soft, muted colors
COLOR_PALETTES.PASTEL; // ["#FFB3BA", "#BAFFC9", "#BAE1FF", ...]
// Grayscale variations
COLOR_PALETTES.MONOCHROME; // ["#2C3E50", "#34495E", "#7F8C8D", ...]
// Natural earth tones
COLOR_PALETTES.EARTH; // ["#8B4513", "#A0522D", "#CD853F", ...]Complete Theme Color Reference
// Primary accent colors
THEME_COLORS.ACCENT_1 through THEME_COLORS.ACCENT_6
// Text and background colors
THEME_COLORS.DARK_1, THEME_COLORS.DARK_2 // Dark colors
THEME_COLORS.LIGHT_1, THEME_COLORS.LIGHT_2 // Light colors
THEME_COLORS.BACKGROUND_1, THEME_COLORS.BACKGROUND_2 // Backgrounds
THEME_COLORS.TEXT_1, THEME_COLORS.TEXT_2 // Text colors
// Link colors
THEME_COLORS.HYPERLINK, THEME_COLORS.FOLLOWED_HYPERLINK🔷 Shapes
// Rectangle
slide.addShape(
"rectangle",
{ x: 100, y: 100 },
{ width: 200, height: 100 },
{
fill: "#ADD8E6", // Light blue
borderColor: "#0000FF", // Blue
borderWidth: 2,
}
);
// Circle
slide.addShape(
"circle",
{ x: 350, y: 100 },
{ width: 100, height: 100 },
{
fill: "#90EE90", // Light green
borderColor: "#00FF00", // Green
borderWidth: 3,
}
);
// Line
slide.addLine(
{ x: 50, y: 250 },
{ x: 450, y: 250 },
{
color: "#FF0000", // Red
width: 4,
style: "dash",
}
);🖼️ Images
// Add image from file
slide.addImageFromFile(
"./path/to/image.png",
{ x: 100, y: 100 },
{ width: 300, height: 200 }
);
// Add image from buffer
const imageBuffer = fs.readFileSync("./image.jpg");
slide.addImageFromBuffer(
imageBuffer,
"jpg",
{ x: 100, y: 100 },
{ width: 300, height: 200 }
);🏗️ Advanced Features
Template Loading
// Load and modify existing template
const pptx = await PowerPointBuilder.fromTemplate("template.pptx");
const slide = pptx.addSlide("New Slide");
// Add content to the slide...
await pptx.saveToFile("modified-presentation.pptx");Presentation Metadata
const pptx = new PowerPointBuilder({
title: "Annual Report 2024",
author: "Finance Team",
subject: "Financial Performance",
company: "Acme Corporation",
description: "Comprehensive financial analysis for 2024",
category: "Business",
keywords: ["finance", "annual", "report", "2024"],
created: new Date(),
modified: new Date(),
});Multi-Slide Presentations
// Slide 1: Title slide
const titleSlide = pptx.addSlide("Annual Report 2024");
titleSlide.addText(
"Annual Report 2024",
{ x: 50, y: 100 },
{ width: 800, height: 100 },
{ fontSize: 36, bold: true, textAlign: "center" }
);
// Slide 2: Sales overview
const salesSlide = pptx.addSlide("Sales Overview");
salesSlide.addChart(/* chart configuration */);
// Slide 3: Financial summary
const financialSlide = pptx.addSlide("Financial Summary");
financialSlide.addTable(/* table configuration */);📐 Coordinate System
PowerPoint uses a coordinate system measured in points (1/72 inch):
- Origin (0,0) is at the top-left corner of the slide
- X-axis increases from left to right
- Y-axis increases from top to bottom
- Standard slide size is 720 points wide × 540 points tall
// Position element 50 points from left, 100 points from top
{ x: 50, y: 100 }
// Size element 400 points wide, 200 points tall
{ width: 400, height: 200 }🧪 Testing
# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage
# Run specific test file
pnpm test chart-builder.test.ts📦 API Reference
PowerPointBuilder
class PowerPointBuilder {
constructor(metadata?: PresentationMetadata);
addSlide(title: string): Slide;
static fromTemplate(templatePath: string): Promise<PowerPointBuilder>;
saveToFile(filePath: string): Promise<void>;
saveToBuffer(): Promise<Buffer>;
}Slide
class Slide {
addText(
text: string,
position: Position,
dimensions: Dimensions,
style?: TextStyle
): void;
addChart(
type: ChartType,
data: ChartData[],
position: Position,
dimensions: Dimensions,
options?: ChartOptions
): void;
addTable(
rows: TableRow[],
position: Position,
dimensions: Dimensions,
options?: TableOptions
): void;
addShape(
type: ShapeType,
position: Position,
dimensions: Dimensions,
style?: ShapeStyle
): void;
addLine(start: Position, end: Position, style?: LineStyle): void;
addImageFromFile(
filePath: string,
position: Position,
dimensions: Dimensions
): void;
addImageFromBuffer(
buffer: Buffer,
format: string,
position: Position,
dimensions: Dimensions
): void;
}Type Definitions
interface Position {
x: number;
y: number;
}
interface Dimensions {
width: number;
height: number;
}
interface TableRow {
cells: TableCell[];
style?: TableRowStyle;
}
interface TableCell {
content: string;
colspan?: number;
rowspan?: number;
style?: TableCellStyle;
font?: FontStyle;
}
interface TableCellStyle {
fill?: ChartColor;
borders?: TableCellBorders;
textAlign?: "left" | "center" | "right" | "justify";
verticalAlign?: "top" | "middle" | "bottom";
padding?: TableCellPadding;
font?: FontStyle;
}
interface TableCellBorders {
// Individual edge control
top?: TableBorder;
bottom?: TableBorder;
left?: TableBorder;
right?: TableBorder;
// Simplified API: apply to all edges at once
all?: TableBorder;
}
interface TableBorder {
show?: boolean;
color?: ChartColor;
width?: number;
style?: "solid" | "dash" | "dot" | "dashDot" | "double";
}🛠️ Development
# Clone the repository
git clone https://github.com/your-username/pptx-builder-js.git
cd pptx-builder-js
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run tests
pnpm test
# Run the demo
pnpm demo🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please read our Contributing Guidelines for more details.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🌟 Examples
Check out the /demo folder for comprehensive examples:
- Advanced Table Demo - Professional tables with all styling features
- Basic Demo - Chart gallery with all chart types and styling
- Simple Test - Quick start examples
- Mavens Demo - Real-world business presentation example
# Run the advanced table demo
npx ts-node demo/advanced-table-demo.ts
# Run the main demo with charts
npx ts-node demo/demo.ts
# Run the simple test
npx ts-node demo/simple-test.ts
# Run the business presentation demo
npx ts-node demo/mavens.ts🚀 What's New
Latest Features
- ✅ Simplified Border API - Set all borders at once with
borders: { all: {...} } - ✅ Advanced Table Support - Professional tables with rich styling
- ✅ Priority-Based Styling - Cell > Row > Column > Table styling hierarchy
- ✅ Column-Specific Styling - Individual column formatting
- ✅ No Border Support - Clean, modern borderless tables
- ✅ Enhanced Color System - Extended theme and custom color support
API Improvements
Before (verbose):
borders: {
top: { show: true, color: '#FF0000', width: 3 },
bottom: { show: true, color: '#FF0000', width: 3 },
left: { show: true, color: '#FF0000', width: 3 },
right: { show: true, color: '#FF0000', width: 3 }
}Now (simplified):
borders: {
all: { show: true, color: '#FF0000', width: 3 }
}🎯 Roadmap
- [x] ✅ Advanced table support with rich styling (COMPLETED)
- [x] ✅ Simplified border API (COMPLETED)
- [x] ✅ Priority-based style resolution (COMPLETED)
- [x] ✅ Column-specific styling (COMPLETED)
- [x] ✅ Comprehensive chart styling with axes, grid lines, and data labels (COMPLETED)
- [x] ✅ Advanced color system with theme colors and variants (COMPLETED)
- [x] ✅ Number formatting for chart axes and data labels (COMPLETED)
- [ ] Animation support for charts and elements
- [ ] Slide transitions
- [ ] More chart types (bubble, radar, waterfall, etc.)
- [ ] SmartArt diagrams
- [ ] Video embedding
- [ ] Advanced template features
- [ ] Export to PDF
- [ ] Presentation notes support
- [ ] Custom slide layouts
- [ ] Text boxes with rich formatting
- [ ] Chart overlays and trendlines
Made with ❤️ by the pptx-builder-js team
