pptx

Read, modify, and create Microsoft PowerPoint presentations with support for templates, charts, tables, and professional formatting.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pptx" with this command: npx skills add sherifeldeeb/agentskills/sherifeldeeb-agentskills-pptx

PPTX Skill

Read, modify, and create Microsoft PowerPoint presentations with support for templates, charts, tables, and professional formatting.

Capabilities

  • Read Presentations: Extract text, images, and notes from PPTX files

  • Create Presentations: Generate new presentations from scratch or templates

  • Modify Presentations: Edit existing slides, add or remove content

  • Charts & Tables: Add data visualizations and formatted tables

  • Template-Based Generation: Use corporate templates for consistency

  • Markdown Conversion: Convert markdown content to presentation slides

Quick Start

from pptx import Presentation from pptx.util import Inches, Pt

Create a presentation

prs = Presentation()

Add a title slide

title_slide_layout = prs.slide_layouts[0] slide = prs.slides.add_slide(title_slide_layout) title = slide.shapes.title subtitle = slide.placeholders[1]

title.text = "Security Assessment" subtitle.text = "Q1 2024 Executive Summary"

prs.save('presentation.pptx')

Usage

Reading Presentations

Extract content from existing PowerPoint files.

Input: Path to a PPTX file

Process:

  • Open presentation with python-pptx

  • Iterate through slides

  • Extract text, shapes, and notes

Example:

from pptx import Presentation from pathlib import Path

def extract_presentation_content(file_path: Path) -> dict: """Extract all content from a PowerPoint presentation.""" prs = Presentation(file_path) content = { 'slide_count': len(prs.slides), 'slides': [] }

for slide_num, slide in enumerate(prs.slides, 1):
    slide_content = {
        'number': slide_num,
        'text': [],
        'notes': ''
    }

    # Extract text from shapes
    for shape in slide.shapes:
        if hasattr(shape, 'text') and shape.text:
            slide_content['text'].append(shape.text)

    # Extract notes
    if slide.has_notes_slide:
        notes_slide = slide.notes_slide
        if notes_slide.notes_text_frame:
            slide_content['notes'] = notes_slide.notes_text_frame.text

    content['slides'].append(slide_content)

return content

Usage

content = extract_presentation_content(Path('briefing.pptx')) for slide in content['slides']: print(f"\n--- Slide {slide['number']} ---") for text in slide['text']: print(text)

Creating Presentations

Generate PowerPoint files from scratch.

Input: Content to include in slides

Process:

  • Create Presentation object

  • Add slides using layouts

  • Populate content

  • Save to file

Example:

from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN

def create_presentation(title: str, slides_content: list, output_path: str): """Create a presentation with multiple slides.""" prs = Presentation()

# Title slide
title_slide = prs.slides.add_slide(prs.slide_layouts[0])
title_slide.shapes.title.text = title
title_slide.placeholders[1].text = "Prepared by Security Team"

# Content slides
for slide_info in slides_content:
    slide_type = slide_info.get('type', 'bullet')

    if slide_type == 'bullet':
        slide = prs.slides.add_slide(prs.slide_layouts[1])
        slide.shapes.title.text = slide_info['title']

        body = slide.placeholders[1]
        tf = body.text_frame

        for i, point in enumerate(slide_info.get('points', [])):
            if i == 0:
                tf.paragraphs[0].text = point
            else:
                p = tf.add_paragraph()
                p.text = point
                p.level = slide_info.get('level', 0)

    elif slide_type == 'blank':
        slide = prs.slides.add_slide(prs.slide_layouts[6])
        # Add custom content

prs.save(output_path)

Usage

slides = [ { 'type': 'bullet', 'title': 'Executive Summary', 'points': [ 'Assessment completed on schedule', '15 vulnerabilities identified', '3 critical findings require immediate attention', 'Overall security posture: Moderate' ] }, { 'type': 'bullet', 'title': 'Critical Findings', 'points': [ 'SQL Injection in login form', 'Exposed admin credentials', 'Unpatched server vulnerabilities' ] } ] create_presentation('Security Assessment Report', slides, 'report.pptx')

Adding Tables

Include formatted tables in slides.

Example:

from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor

def add_table_slide(prs, title: str, headers: list, rows: list): """Add a slide with a formatted table.""" slide = prs.slides.add_slide(prs.slide_layouts[5]) # Title only layout slide.shapes.title.text = title

# Define table dimensions
x, y = Inches(0.5), Inches(1.5)
cx, cy = Inches(9), Inches(0.8 * (len(rows) + 1))

table = slide.shapes.add_table(
    len(rows) + 1, len(headers), x, y, cx, cy
).table

# Style header row
for col_idx, header in enumerate(headers):
    cell = table.cell(0, col_idx)
    cell.text = header
    cell.fill.solid()
    cell.fill.fore_color.rgb = RGBColor(44, 62, 80)
    paragraph = cell.text_frame.paragraphs[0]
    paragraph.font.bold = True
    paragraph.font.color.rgb = RGBColor(255, 255, 255)
    paragraph.font.size = Pt(12)

# Add data rows
for row_idx, row_data in enumerate(rows, 1):
    for col_idx, value in enumerate(row_data):
        cell = table.cell(row_idx, col_idx)
        cell.text = str(value)
        paragraph = cell.text_frame.paragraphs[0]
        paragraph.font.size = Pt(11)

return slide

Usage

prs = Presentation() headers = ['Finding', 'Severity', 'Status', 'Due Date'] rows = [ ['SQL Injection', 'Critical', 'Open', '2024-02-01'], ['XSS Vulnerability', 'High', 'In Progress', '2024-02-15'], ['Weak Passwords', 'Medium', 'Fixed', '2024-01-20'] ] add_table_slide(prs, 'Findings Summary', headers, rows) prs.save('findings.pptx')

Adding Charts

Create data visualizations in slides.

Example:

from pptx import Presentation from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE from pptx.util import Inches

def add_chart_slide(prs, title: str, chart_type: str, categories: list, series: dict): """Add a slide with a chart.""" slide = prs.slides.add_slide(prs.slide_layouts[5]) slide.shapes.title.text = title

# Create chart data
chart_data = CategoryChartData()
chart_data.categories = categories

for series_name, values in series.items():
    chart_data.add_series(series_name, values)

# Determine chart type
chart_types = {
    'bar': XL_CHART_TYPE.BAR_CLUSTERED,
    'column': XL_CHART_TYPE.COLUMN_CLUSTERED,
    'pie': XL_CHART_TYPE.PIE,
    'line': XL_CHART_TYPE.LINE
}
xl_chart_type = chart_types.get(chart_type, XL_CHART_TYPE.COLUMN_CLUSTERED)

# Add chart to slide
x, y, cx, cy = Inches(1), Inches(1.5), Inches(8), Inches(5)
chart = slide.shapes.add_chart(xl_chart_type, x, y, cx, cy, chart_data).chart

return slide

Usage

prs = Presentation()

Add title slide

title_slide = prs.slides.add_slide(prs.slide_layouts[0]) title_slide.shapes.title.text = 'Security Metrics Dashboard'

Add bar chart

categories = ['Critical', 'High', 'Medium', 'Low'] series = {'Findings': [3, 8, 15, 22]} add_chart_slide(prs, 'Findings by Severity', 'column', categories, series)

Add pie chart

add_chart_slide(prs, 'Severity Distribution', 'pie', categories, series)

prs.save('metrics.pptx')

Using Templates

Apply corporate templates for consistent branding.

Example:

from pptx import Presentation from pptx.util import Inches, Pt

def create_from_template(template_path: str, output_path: str, content: list): """Create presentation from a template.""" prs = Presentation(template_path)

for slide_content in content:
    # Use template's slide layouts
    layout_index = slide_content.get('layout', 1)
    slide = prs.slides.add_slide(prs.slide_layouts[layout_index])

    # Fill in placeholders
    if slide.shapes.title:
        slide.shapes.title.text = slide_content.get('title', '')

    # Fill body placeholder if available
    for placeholder in slide.placeholders:
        if placeholder.placeholder_format.idx == 1:  # Body placeholder
            tf = placeholder.text_frame
            points = slide_content.get('points', [])
            for i, point in enumerate(points):
                if i == 0:
                    tf.paragraphs[0].text = point
                else:
                    p = tf.add_paragraph()
                    p.text = point

prs.save(output_path)

Usage

content = [ { 'layout': 1, 'title': 'Assessment Overview', 'points': ['Scope: Web Application', 'Duration: 2 weeks', 'Methodology: OWASP'] }, { 'layout': 1, 'title': 'Key Findings', 'points': ['3 Critical vulnerabilities', '5 High severity issues', '12 Medium findings'] } ] create_from_template('corporate_template.pptx', 'assessment.pptx', content)

Markdown to Slides

Convert markdown content to presentation slides.

Example:

from pptx import Presentation from pptx.util import Inches, Pt import re

def markdown_to_slides(markdown_content: str, output_path: str): """Convert markdown to PowerPoint slides.""" prs = Presentation()

# Split by headers (slides)
sections = re.split(r'\n(?=# )', markdown_content.strip())

for section in sections:
    lines = section.strip().split('\n')
    if not lines:
        continue

    # Get title (# heading)
    title_match = re.match(r'^#\s+(.+)$', lines[0])
    if not title_match:
        continue

    title = title_match.group(1)

    # Get bullet points
    points = []
    for line in lines[1:]:
        bullet_match = re.match(r'^[-*]\s+(.+)$', line.strip())
        if bullet_match:
            points.append(bullet_match.group(1))

    # Create slide
    if points:
        slide = prs.slides.add_slide(prs.slide_layouts[1])
        slide.shapes.title.text = title

        body = slide.placeholders[1]
        tf = body.text_frame

        for i, point in enumerate(points):
            if i == 0:
                tf.paragraphs[0].text = point
            else:
                p = tf.add_paragraph()
                p.text = point
    else:
        # Title only slide
        slide = prs.slides.add_slide(prs.slide_layouts[5])
        slide.shapes.title.text = title

prs.save(output_path)

Usage

markdown = """

Security Assessment Report

  • Conducted comprehensive penetration test
  • Identified 15 vulnerabilities
  • Prioritized remediation roadmap

Critical Findings

  • SQL Injection in authentication module
  • Remote code execution via file upload
  • Exposed API credentials in source code

Recommendations

  • Implement input validation
  • Deploy WAF protection
  • Rotate all exposed credentials """ markdown_to_slides(markdown, 'assessment.pptx')

Adding Speaker Notes

Include speaker notes for presentations.

Example:

from pptx import Presentation

def add_slide_with_notes(prs, title: str, points: list, notes: str): """Add a slide with speaker notes.""" slide = prs.slides.add_slide(prs.slide_layouts[1]) slide.shapes.title.text = title

body = slide.placeholders[1]
tf = body.text_frame

for i, point in enumerate(points):
    if i == 0:
        tf.paragraphs[0].text = point
    else:
        p = tf.add_paragraph()
        p.text = point

# Add speaker notes
notes_slide = slide.notes_slide
notes_slide.notes_text_frame.text = notes

return slide

Usage

prs = Presentation()

add_slide_with_notes( prs, 'Executive Summary', ['15 findings identified', '3 critical issues', 'Immediate action required'], 'Key talking points:\n- Emphasize urgency of critical findings\n- Discuss remediation timeline\n- Request budget approval for fixes' )

prs.save('briefing.pptx')

Configuration

Environment Variables

Variable Description Required Default

PPTX_TEMPLATE_DIR

Default template directory No ./assets/templates

Script Options

Option Type Description

--input

path Input file (PPTX or Markdown)

--output

path Output PPTX file

--template

path Template to use

--verbose

flag Enable verbose logging

Examples

Example 1: Security Briefing Generator

Scenario: Generate executive security briefing from findings data.

from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor

def generate_security_briefing(findings: list, output_path: str): """Generate a security briefing presentation.""" prs = Presentation()

# Title slide
title_slide = prs.slides.add_slide(prs.slide_layouts[0])
title_slide.shapes.title.text = 'Security Assessment Briefing'
title_slide.placeholders[1].text = 'Confidential - Executive Summary'

# Summary statistics
critical = sum(1 for f in findings if f['severity'] == 'Critical')
high = sum(1 for f in findings if f['severity'] == 'High')
medium = sum(1 for f in findings if f['severity'] == 'Medium')

summary_slide = prs.slides.add_slide(prs.slide_layouts[1])
summary_slide.shapes.title.text = 'Executive Summary'

body = summary_slide.placeholders[1]
tf = body.text_frame
tf.paragraphs[0].text = f'Total Findings: {len(findings)}'
tf.add_paragraph().text = f'Critical: {critical}'
tf.add_paragraph().text = f'High: {high}'
tf.add_paragraph().text = f'Medium: {medium}'

# Individual finding slides
for finding in findings:
    if finding['severity'] in ['Critical', 'High']:
        slide = prs.slides.add_slide(prs.slide_layouts[1])
        slide.shapes.title.text = f"[{finding['severity']}] {finding['title']}"

        body = slide.placeholders[1]
        tf = body.text_frame
        tf.paragraphs[0].text = finding.get('description', '')
        tf.add_paragraph().text = f"Risk: {finding.get('risk', 'N/A')}"
        tf.add_paragraph().text = f"Remediation: {finding.get('remediation', 'N/A')}"

prs.save(output_path)

Usage

findings = [ { 'title': 'SQL Injection', 'severity': 'Critical', 'description': 'Authentication bypass via SQL injection', 'risk': 'Complete system compromise', 'remediation': 'Implement parameterized queries' }, { 'title': 'XSS Vulnerability', 'severity': 'High', 'description': 'Stored XSS in user profile', 'risk': 'Session hijacking', 'remediation': 'Implement output encoding' } ] generate_security_briefing(findings, 'security_briefing.pptx')

Example 2: Metrics Dashboard Presentation

Scenario: Create a metrics dashboard presentation with charts.

from pptx import Presentation from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE from pptx.util import Inches

def create_metrics_dashboard(metrics: dict, output_path: str): """Create a metrics dashboard presentation.""" prs = Presentation()

# Title slide
title_slide = prs.slides.add_slide(prs.slide_layouts[0])
title_slide.shapes.title.text = 'Security Metrics Dashboard'
title_slide.placeholders[1].text = 'Monthly Report'

# Vulnerability trend chart
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = 'Vulnerability Trend'

chart_data = CategoryChartData()
chart_data.categories = metrics['months']
chart_data.add_series('Open', metrics['open_vulns'])
chart_data.add_series('Closed', metrics['closed_vulns'])

chart = slide.shapes.add_chart(
    XL_CHART_TYPE.LINE, Inches(1), Inches(1.5), Inches(8), Inches(5), chart_data
).chart

# Severity distribution
slide2 = prs.slides.add_slide(prs.slide_layouts[5])
slide2.shapes.title.text = 'Current Severity Distribution'

chart_data2 = CategoryChartData()
chart_data2.categories = list(metrics['severity_dist'].keys())
chart_data2.add_series('Count', list(metrics['severity_dist'].values()))

slide2.shapes.add_chart(
    XL_CHART_TYPE.PIE, Inches(2), Inches(1.5), Inches(6), Inches(5), chart_data2
)

prs.save(output_path)

Usage

metrics = { 'months': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], 'open_vulns': [45, 52, 48, 35, 28, 22], 'closed_vulns': [30, 45, 55, 60, 65, 70], 'severity_dist': {'Critical': 3, 'High': 12, 'Medium': 25, 'Low': 40} } create_metrics_dashboard(metrics, 'dashboard.pptx')

Limitations

  • Animations: Cannot create or modify slide animations

  • Transitions: Slide transitions are not supported

  • Videos: Limited support for embedded videos

  • Audio: Cannot add or modify audio clips

  • SmartArt: Cannot create SmartArt graphics

  • Complex Charts: Some advanced chart types may have limited support

Troubleshooting

Layout Not Found

Problem: Getting KeyError when accessing slide layout

Solution: Check available layouts:

prs = Presentation() for i, layout in enumerate(prs.slide_layouts): print(f"{i}: {layout.name}")

Text Not Fitting

Problem: Text overflows placeholder

Solution: Adjust font size or use auto-fit:

from pptx.util import Pt

tf = placeholder.text_frame tf.auto_size = True

Or manually set font size

for paragraph in tf.paragraphs: paragraph.font.size = Pt(14)

Template Issues

Problem: Custom template not applying correctly

Solution: Verify template has expected placeholders:

prs = Presentation('template.pptx') for layout in prs.slide_layouts: print(f"\n{layout.name}:") for placeholder in layout.placeholders: print(f" {placeholder.placeholder_format.idx}: {placeholder.name}")

Related Skills

  • docx: Convert Word reports to presentations

  • xlsx: Import data for charts and tables

  • image-generation: Create visual assets for slides

  • pdf: Export presentations to PDF

References

  • Detailed API Reference

  • python-pptx Documentation

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

email-forensics

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

disk-forensics

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

forensic-reporting

No summary provided by upstream source.

Repository SourceNeeds Review