OptionalFinanceVersion 1.0.0

Pptx Author: Build Headless PowerPoint Decks with python-pptx

Build PowerPoint decks headless with python-pptx.

Written by Neura Market from the official Hermes Agent documentation for Pptx Author. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

Generating Model-Bound Financial Decks with python-pptx

This reference describes how to produce a .pptx file on disk using python-pptx for financial decks—pitch decks, IC memos, or earnings notes—where every number traces to a source workbook. The skill is designed for headless environments without Office or MCP for live PowerPoint.

When to Use This Skill

Use this skill when you need to produce a PowerPoint file as an artifact, not a live session. It is appropriate for building financial pitch decks, IC memos, or earnings notes where numbers must be bound to a model workbook. Use it in a headless environment without Office or MCP for live PowerPoint. Every figure on a slide must trace to a specific cell or named range in an Excel model.

Prerequisites

Before using this skill, ensure you have:

  • A Python environment with python-pptx >=0.6 installed.
  • openpyxl installed if binding to an Excel model.
  • An Excel model workbook at ./out/model.xlsx with named ranges or specific cells defined.
  • The model workbook recalculated before reading (via excel-author recalc helper or manual open/save).
  • Optional: a firm template at ./templates/firm-template.pptx.
  • Optional: pre-rendered chart PNGs at ./out/charts/ for embedding.

Installation

Install the required library with:

pip install "python-pptx>=0.6"

Capabilities

The skill can:

  • Create a .pptx file from Python using python-pptx.
  • Load a firm template from ./templates/firm-template.pptx if present; otherwise start blank.
  • Add slides with title and content (title slide, title-only, table, image).
  • Add tables with headers and data rows.
  • Embed PNG images (e.g., charts rendered from the model).
  • Bind deck numbers to an Excel model via openpyxl reading named ranges or cells.
  • Write output to ./out/<filename>.pptx, creating ./out/ if missing.
  • Return the relative path of the output file in the final message.

Parameters

  • template path: Path to firm template file (./templates/firm-template.pptx). If it exists, the deck inherits branded colors, fonts, and master layouts. Optional; if missing, start blank.
  • model workbook path: Path to the Excel model (./out/model.xlsx) from which to read numbers via named ranges or cells. Optional; if used, must recalc the workbook first.
  • output filename: Name of the .pptx file to write inside ./out/ (e.g., pitch-aurora.pptx). Required.

Procedure: Create a Pitch Deck Bound to an Excel Model

Follow these steps in order:

  1. Install python-pptx (>=0.6) via pip.
  2. Check if ./templates/firm-template.pptx exists; if yes, load it as Presentation(str(template)), else Presentation().
  3. Create slides using prs.slides.add_slide(prs.slide_layouts[<index>]).
  4. For each slide, set slide.shapes.title.text to a takeaway sentence (one idea per slide).
  5. For a title slide, set slide.placeholders[1].text for the subtitle.
  6. For tables, use slide.shapes.add_table(rows, cols, left, top, width, height) then populate cells.
  7. For embedded charts, use slide.shapes.add_picture(png_path, left, top, width=Inches(8)).
  8. Read model values from ./out/model.xlsx using openpyxl: load_workbook(data_only=True), define a helper to resolve named ranges (wb.defined_names[name], iterate destinations, read cell value).
  9. Recalculate the workbook before reading (use excel-author recalc helper or open/save in Excel) because openpyxl only sees computed values if the sheet was already calculated.
  10. Build slide titles and table content using those values (e.g., f-string with ${value:.2f}).
  11. Ensure every figure footnotes its source, for example: Revenue: $1,250M (Source: model.xlsx, Inputs!C3).
  12. Create ./out/ directory if not exists: Path('./out').mkdir(exist_ok=True).
  13. Save the presentation: prs.save('./out/<filename>.pptx').
  14. Return the relative path of the saved file.

Loading a Template or Starting Blank

The following code loads the firm template if it exists, or starts with a blank presentation:

from pptx import Presentation
from pathlib import Path

template = Path("./templates/firm-template.pptx")
prs = Presentation(str(template)) if template.exists() else Presentation()

Building a Complete Deck

The following example creates a pitch deck with a title slide, valuation summary table, and an embedded chart:

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

template = Path("./templates/firm-template.pptx")
prs = Presentation(str(template)) if template.exists() else Presentation()

# Title slide
slide = prs.slides.add_slide(prs.slide_layouts[0])
slide.shapes.title.text = "Project Aurora — Strategic Alternatives"
slide.placeholders[1].text = "Preliminary Discussion Materials"

# Valuation summary slide (title-only layout)
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Valuation implies $38–$52 per share across methodologies"

# Add a table bound to model outputs
rows, cols = 5, 4
tbl_shape = slide.shapes.add_table(rows, cols,
                                   Inches(0.5), Inches(1.5),
                                   Inches(9), Inches(3))
tbl = tbl_shape.table
headers = ["Methodology", "Low ($)", "Mid ($)", "High ($)"]
for c, h in enumerate(headers):
    tbl.cell(0, c).text = h

# In a real deck, read these from the model workbook with openpyxl
data = [
    ("Trading comps",     "35", "41", "48"),
    ("Precedent M&A",     "39", "45", "52"),
    ("DCF (base)",        "36", "43", "51"),
    ("LBO (10% IRR)",     "33", "38", "44"),
]
for r, row in enumerate(data, start=1):
    for c, val in enumerate(row):
        tbl.cell(r, c).text = val

# Embed a chart rendered from the model
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Football field — current price $42"
slide.shapes.add_picture("./out/charts/football_field.png",
                         Inches(1), Inches(1.8), width=Inches(8))

Path("./out").mkdir(exist_ok=True)
prs.save("./out/pitch-aurora.pptx")

In this example, the valuation summary table shows a range from $38 to $52 per share. The football field chart is embedded at the current price of $42. The LBO row uses a 10% IRR assumption. The trading comps methodology shows a low of $35, mid of $41, and high of $48. The precedent M&A row shows a low of $39, mid of $45, and high of $52. The DCF base case shows a low of $36, mid of $43, and high of $51. The LBO row shows a low of $33, mid of $38, and high of $44.

Binding Numbers to an Excel Model

Use openpyxl to read values from the model workbook. The following helper resolves named ranges:

from openpyxl import load_workbook

wb = load_workbook("./out/model.xlsx", data_only=True)
def nr(name):
    """Resolve a named range to its current computed value."""
    rng = wb.defined_names[name]
    sheet, coord = next(rng.destinations)
    return wb[sheet][coord].value

revenue_fy24 = nr("RevenueFY24")
implied_mid  = nr("ImpliedSharePriceBase")

Then use the values in slide titles:

slide.shapes.title.text = f"Implied share price of ${implied_mid:.2f} (base case)"

Every number on a slide must trace to the model workbook (sheet and cell). Never transcribe from memory or summary.

Embedding Charts

Use PNG-from-model for charts when fidelity matters. Native pptx.chart charts are fragile and may not match firm conventions. Embed a chart with:

from pptx.util import Inches
slide.shapes.add_picture("./out/charts/football_field.png",
                         Inches(1), Inches(2),
                         width=Inches(8))

Constraints and Caveats

  • Output must be written to ./out/<filename>.pptx; create ./out/ if missing.
  • Return the relative path in the final message.
  • Every number on a slide must trace to the model workbook (sheet and cell). Never transcribe from memory or summary.
  • Use PNG-from-model for charts (not native pptx charts) when fidelity matters; native charts are fragile and may not match firm conventions.
  • This skill only writes a file; never emails, uploads, or posts.
  • Do not use for live PowerPoint sessions (use Office MCP instead).
  • Do not use for non-financial slideware (use broader powerpoint skill).
  • Do not use for decks requiring heavy animation, transitions, or speaker notes (use broader powerpoint skill).
  • openpyxl only sees computed values if the workbook was already calculated; recalc before reading (use excel-author recalc helper or open/save in Excel).
  • One idea per slide: the title states the takeaway, the body supports it.

Failure Modes

  • Missing template file causes fallback to blank presentation (no error).
  • Model workbook not recalculated before reading yields stale or None values from openpyxl.
  • Named range not found in workbook raises KeyError when iterating destinations.
  • Output directory ./out/ not created before save causes FileNotFoundError.
  • python-pptx not installed or wrong version causes ImportError.
  • Image file (PNG) not found at specified path causes add_picture to fail.

Slide-Type Checklist for Pitch Decks

A typical pitch deck includes: cover, disclaimer, TOC, situation overview, company snapshot, market context, valuation summary (football field), trading comps detail, precedent transactions detail, DCF summary, illustrative LBO, process considerations, and appendix.

Authoring a Pitch Deck

When authoring a pitch deck, use the pptx-author skill to produce the file. The output filename should reflect the deck type, for example pitch-deck. The final file is saved to ./out/.pptx.

Skills the docs pair this with

More Finance skills