PowerPoint Generation with pptxgenjs
SkillDocs & knowledgeLets your agent create, edit, and analyze PowerPoint (.pptx) files.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the PowerPoint Generation with pptxgenjs skill
About this capability
Generating PowerPoint presentations with pptxgenjs in Node.js. Use when creating automated presentations, slide decks, pitch decks, or reports in .pptx format from data.
What this skill tells your AI
The instructions your AI receives, as published by sabahattink/antigravity-fullstack-hq in skills/pptx-official/SKILL.md and read by ahel’s review.
Installation
npm install pptxgenjs
npm install -D @types/node
Basic Presentation
import PptxGenJS from 'pptxgenjs'
async function generatePresentation(data: PresentationData): Promise<Buffer> {
const pptx = new PptxGenJS()
// Global settings
pptx.author = 'Antigravity HQ'
pptx.company = 'Antigravity'
pptx.title = data.title
pptx.subject = data.subject
pptx.layout = 'LAYOUT_WIDE' // 16:9
// ─── Title Slide ─────────────────────────────────────────
const titleSlide = pptx.addSlide()
titleSlide.background = { color: '1E3A5F' }
titleSlide.addText(data.title, {
x: '10%',
y: '35%',
w: '80%',
h: '20%',
fontSize: 40,
bold: true,
color: 'FFFFFF',
align: 'center',
fontFace: 'Calibri',
})
titleSlide.addText(data.subtitle, {
x: '15%',
y: '60%',
w: '70%',
h: '10%',
fontSize: 20,
color: 'B0C4DE',
align: 'center',
})
titleSlide.addText(new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long' }), {
x: '0%',
y: '88%',
w: '100%',
h: '8%',
fontSize: 12,
color: '7094B5',
align: 'center',
})
// ─── Content Slides ───────────────────────────────────────
for (const section of data.sections) {
addContentSlide(pptx, section)
}
// ─── Chart Slide ──────────────────────────────────────────
if (data.chartData) {
addChartSlide(pptx, data.chartData)
}
// ─── Summary Slide ────────────────────────────────────────
addSummarySlide(pptx, data.keyPoints)
// Return as buffer
const buffer = await pptx.write({ outputType: 'nodebuffer' }) as Buffer
return buffer
}
Content Slide with Bullets
function addContentSlide(pptx: PptxGenJS, section: Section) {
const slide = pptx.addSlide()
// Slide header bar
slide.addShape(pptx.ShapeType.rect, {
x: 0, y: 0, w: '100%', h: 0.8,
fill: { color: '2563EB' },
line: { color: '2563EB' },
})
// Title
slide.addText(section.title, {
x: 0.3,
y: 0.1,
w: '90%',
h: 0.6,
fontSize: 22,
bold: true,
color: 'FFFFFF',
fontFace: 'Calibri',
})
// Bullet points
slide.addText(
section.bullets.map(bullet => ({
text: bullet,
options: {
bullet: { type: 'bullet', characterCode: '25CF' }, // filled circle
paraSpaceAfter: 8,
},
})),
{
x: 0.5,
y: 1.1,
w: '90%',
h: '75%',
fontSize: 16,
color: '374151',
fontFace: 'Calibri',
valign: 'top',
}
)
// Slide number
slide.addText(`${section.slideNumber}`, {
x: '93%',
y: '92%',
w: '5%',
h: '6%',
fontSize: 10,
color: '9CA3AF',
align: 'right',
})
}
Chart Slide
function addChartSlide(pptx: PptxGenJS, chartData: ChartData) {
const slide = pptx.addSlide()
// Header
slide.addShape(pptx.ShapeType.rect, {
x: 0, y: 0, w: '100%', h: 0.8,
fill: { color: '2563EB' },
line: { color: '2563EB' },
})
slide.addText(chartData.title, {
x: 0.3, y: 0.1, w: '90%', h: 0.6,
fontSize: 22, bold: true, color: 'FFFFFF',
})
// Bar chart
slide.addChart(pptx.ChartType.bar, [
{
name: chartData.seriesName,
labels: chartData.labels,
values: chartData.values,
},
], {
x: 0.5,
y: 1.0,
w: 9.0,
h: 5.0,
chartColors: ['2563EB', '10B981', 'F59E0B', 'EF4444'],
showValue: true,
showLegend: true,
legendPos: 'b',
dataLabelFontSize: 10,
catAxisLabelFontSize: 11,
valAxisLabelFontSize: 11,
title: chartData.title,
showTitle: false,
})
}
// Line chart for trends
slide.addChart(pptx.ChartType.line, [
{ name: 'Revenue', labels: months, values: revenueData },
{ name: 'Costs', labels: months, values: costData },
], {
x: 0.5, y: 1.0, w: 9.0, h: 5.0,
lineSize: 2,
showLegend: true,
showMarker: true,
chartColors: ['2563EB', 'EF4444'],
})
Table Slide
function addTableSlide(pptx: PptxGenJS, tableData: TableData) {
const slide = pptx.addSlide()
const rows: PptxGenJS.TableRow[] = [
// Header row
tableData.headers.map(h => ({
text: h,
options: {
bold: true,
color: 'FFFFFF',
fill: { color: '2563EB' },
fontSize: 12,
align: 'center' as const,
},
})),
// Data rows
...tableData.rows.map((row, i) =>
row.map(cell => ({
text: cell,
options: {
fontSize: 11,
color: '374151',
fill: i % 2 === 0 ? { color: 'F8FAFC' } : { color: 'FFFFFF' },
},
}))
),
]
slide.addTable(rows, {
x: 0.3,
y: 1.0,
w: 9.4,
border: { type: 'solid', color: 'E5E7EB', pt: 0.5 },
colW: tableData.columnWidths,
})
}
NestJS Integration
// presentations/presentations.service.ts
@Injectable()
export class PresentationsService {
async generateReport(reportId: string): Promise<Buffer> {
const report = await this.reportsRepo.findOneOrFail(reportId)
return generatePresentation({
title: report.title,
subtitle: report.period,
subject: 'Monthly Report',
sections: report.sections.map(s => ({
title: s.heading,
bullets: s.points,
slideNumber: s.order,
})),
chartData: {
title: 'Revenue Trend',
seriesName: 'Revenue',
labels: report.chart.months,
values: report.chart.values,
},
keyPoints: report.summary,
})
}
}
// presentations/presentations.controller.ts
@Get(':id/pptx')
@UseGuards(JwtAuthGuard)
async downloadPptx(
@Param('id') id: string,
@Res() res: Response,
) {
const buffer = await this.presentationsService.generateReport(id)
res.set({
'Content-Type': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'Content-Disposition': `attachment; filename="report-${id}.pptx"`,
'Content-Length': buffer.length,
})
res.end(buffer)
}
Forbidden Patterns
- Never use absolute pixel values for positioning — use percentages or inch values for portability
- Never forget to
await pptx.write()— it returns a Promise - Never include user-provided text without escaping HTML entities in text fields
- Never create slides in a loop without checking memory — large decks need streaming or chunking
Signals
- GitHub stars
- 30
- Forks
- 9
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
pptx-official- Source
- github.com/sabahattink/antigravity-fullstack-hq