EasyPPTX
A Python library for easily creating and manipulating PowerPoint presentations programmatically with simple APIs, designed to be easy for both humans and AI assistants to use.
- Github repository: https://github.com/Ameyanagi/EasyPPTX/
- Documentation https://Ameyanagi.github.io/EasyPPTX/
Features
- Simple, intuitive API for PowerPoint manipulation
- Grid-first layout system: spans, weighted rows/columns, auto-flow, cell styling
- Markdown → deck conversion (
Presentation.from_markdown) - Percentage positions as plain numbers (
x=10is 10%); inches viain_(1.5) - Bullet lists with nesting, speaker notes, and multi-series charts
- Reusable style objects and built-in themes (light / dark / corporate)
- Support for reference PowerPoint templates and TOML template files
- Loud, predictable errors — unknown parameters warn instead of vanishing
- Optimized for use with AI assistants and LLMs
- Built on top of python-pptx with a more user-friendly interface
Installation
pip install easypptx
# With optional extras:
pip install "easypptx[dataframe]" # pandas support (tables/charts from DataFrames)
pip install "easypptx[plot]" # matplotlib figure support
pip install "easypptx[all]" # everything
Quick Start
The fastest way to build a deck is the grid workflow — one call creates a
slide with a title and a grid, then grid[row, col] places content:
from easypptx import Presentation
pres = Presentation()
# One call: slide with title + 2x2 grid
slide, grid = pres.add_grid_slide(rows=2, cols=2, title="Quarterly Review")
grid[0, 0].add_text("Revenue up 12%", font_size=20, align="center", vertical="middle")
grid[0, 1].add_table([["Region", "Sales"], ["East", 120], ["West", 95]], has_header=True)
grid[1, :].add_text("Next steps: expand pilot", font_size=18) # spans the bottom row
pres.save("review.pptx")
Positions are percentages — as plain numbers or strings — and physical
units use in_():
from easypptx import in_
slide.add_text("Centered band", x=10, y=45, width=80, height=10) # 10% / 45% / ...
slide.add_image(image_path="logo.png", x=in_(0.5), width=in_(1.5)) # absolute inches
Markdown → deck
from easypptx import Presentation
pres = Presentation.from_markdown("deck.md") # or a markdown string
pres.save("deck.pptx")
---
theme: dark
---
# Q3 Review
Finance team
## Highlights <!-- notes: keep this section short -->
- Revenue up 12%
- EMEA strongest region
- Costs down 3%
::: columns

| Region | Sales |
|--------|-------|
| East | 120 |
:::
Themes and styles
from easypptx import Presentation, TextStyle
pres = Presentation(theme="dark") # light / dark / corporate, or a custom Theme
heading = TextStyle(font_size=28, font_bold=True, color="cyan")
slide = pres.add_slide(title="Styled")
slide.add_text("Reusable styling", style=heading)
slide.add_bullets(["First point", ("Nested detail", 1), "Second point"])
slide.notes = "Speaker notes go here."
Content can also be placed directly on a slide with percentage-based positions:
from easypptx import Presentation
import pandas as pd
# Create a new presentation (uses 16:9 aspect ratio by default)
pres = Presentation()
# Add a slide with a title
slide = pres.add_slide(title="EasyPPTX Demo")
# Add text directly to the slide
slide.add_text(
text="This presentation was created with EasyPPTX",
x="10%",
y="20%",
width="80%",
height="10%",
font_size=24
)
# Add an image
slide.add_image(
image_path="path/to/image.png",
x="10%",
y="35%",
width="40%"
)
# Create a table
data = [["Name", "Value"], ["Item 1", 100], ["Item 2", 200]]
slide.add_table(
data=data,
x="60%",
y="35%",
width="30%",
has_header=True
)
# Add a slide with a chart from pandas DataFrame
chart_slide = pres.add_slide(title="Chart Example")
df = pd.DataFrame({"Category": ["A", "B", "C"], "Value": [10, 20, 30]})
chart_slide.add_chart(
data=df,
chart_type="pie",
category_column="Category",
value_column="Value",
x="20%",
y="20%",
width="60%",
height="60%",
title="Sample Chart"
)
# Save the presentation
pres.save("example.pptx")
Aspect Ratio Options
EasyPPTX supports multiple aspect ratios for presentations:
# Default 16:9 widescreen presentation
pres = Presentation()
# Standard 4:3 presentation
pres = Presentation(aspect_ratio="4:3")
# Other supported options: "16:10", "A4", "LETTER"
pres = Presentation(aspect_ratio="16:10")
# Custom dimensions (width and height in inches)
pres = Presentation(width_inches=12, height_inches=9)
Reference Templates
You can use multiple template formats with EasyPPTX for consistent presentation designs.
Custom Reference PPTX Files
Use custom PPTX files as references for your presentations:
# Use a custom reference PPTX file (keeping all layouts and styles)
pres = Presentation(reference_pptx="path/to/your/reference.pptx")
# Specify a custom blank layout index (if the default auto-detection doesn't work)
pres = Presentation(
reference_pptx="path/to/your/reference.pptx",
blank_layout_index=2 # Use the third layout as blank
)
# When opening existing presentations, you can also specify blank layout
pres = Presentation.open(
"path/to/existing.pptx",
blank_layout_index=4 # Use the fifth layout as blank
)
TOML Template Initialization
You can initialize a presentation with a TOML template file, which will be used for all slides by default:
# Create a presentation with a default template
pres = Presentation(template_toml="templates/business_title.toml")
# Add a slide - it will automatically use the template
slide = pres.add_slide(title="Slide with Default Template")
# Add a slide with a different template, overriding the default
slide2 = pres.add_slide(
title="Slide with Different Template",
template_toml="templates/tech_dark.toml"
)
# Add a slide without any template
slide3 = pres.add_slide(
title="Standard Slide",
template_toml=False # Explicitly disable the default template for this slide
)
TOML Template Reference PPTX Specification
You can also specify reference PPTX files in TOML template files:
# Specify the reference PPTX file path (absolute or relative to the TOML file)
reference_pptx = "../references/my_template.pptx"
# Optionally specify the blank layout index
blank_layout_index = 3
# Rest of your template content
[title]
text = "Presentation Title"
position = { x = "10%", y = "30%", width = "80%", height = "20%" }
font = { name = "Meiryo", size = 44, bold = true }
align = "center"
# ...
Then use the template in your code:
from easypptx import Presentation
from easypptx.template import TemplateManager
# Load the template file
template_manager = TemplateManager()
template_name = template_manager.load("path/to/template.toml")
# Create a presentation and use the template
pres = Presentation()
slide = pres.add_slide_from_template(template_name)
# The reference PPTX specified in the TOML is automatically loaded
Percentage-Based Positioning
Position and size elements using percentages of the slide dimensions:
# Add text at 20% from the left, 30% from the top, 60% width, 10% height
text.add_paragraph("Positioned with percentages", x="20%", y="30%", width="60%", height="10%")
# Add an image at 10% from the left, 50% from the top, 40% width
img.add("image.png", x="10%", y="50%", width="40%")
# Add a shape using percentages
slide.add_shape(
x="70%",
y="50%",
width="20%",
height="20%",
fill_color="blue"
)
Auto-Alignment of Multiple Objects
Easily align multiple objects in a grid, horizontal, or vertical layout:
# Define objects to be added
objects = [
{"type": "text", "text": "Item 1", "color": "black"},
{"type": "text", "text": "Item 2", "color": "red"},
{"type": "text", "text": "Item 3", "color": "blue"},
{"type": "shape", "shape_type": MSO_SHAPE.RECTANGLE, "fill_color": "green"}
]
# Add objects in a grid layout (2x2)
slide.add_multiple_objects(
objects_data=objects,
layout="grid",
padding_percent=5.0,
start_x="10%",
start_y="30%",
width="80%",
height="60%"
)
# Add objects in a horizontal layout (row)
slide.add_multiple_objects(
objects_data=objects,
layout="horizontal",
start_y="50%",
height="20%"
)
Enhanced Grid Layout System
EasyPPTX provides a powerful Grid layout system for creating complex and responsive layouts:
Creating Grids with Add Grid Slide
Create a slide with a grid layout in one step:
# Create a slide with a 2x2 grid
slide, grid = pres.add_grid_slide(
title="Grid Layout Example",
rows=2,
cols=2,
title_height="10%",
padding=5.0
)
# Add content directly to grid cells using the enhanced access API
grid[0, 0].add_text(
text="Top Left Cell",
font_size=18,
align="center",
vertical="middle"
)
grid[0, 1].add_image(
image_path="path/to/image.jpg",
maintain_aspect_ratio=True
)
# Generate a matplotlib figure
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
ax.set_title("Sample Plot")
# Add the matplotlib figure to a grid cell
grid[1, 0].add_pyplot(figure=fig, dpi=150)
# Add a table to the remaining cell
grid[1, 1].add_table(
data=[["A", "B"], [1, 2]],
has_header=True
)
Grid Iteration and Indexing
Easily access and iterate through grid cells:
# Access cells using indexing
cell1 = grid[0, 0] # Row 0, Column 0
cell2 = grid[3] # Flat index (row-major order)
# Iterate through all cells
for cell in grid:
print(f"Cell at {cell.row}, {cell.col}")
# Use the flat property for flat iteration
for cell in grid.flat:
print(f"Cell content: {cell.content}")
# Merge cells to create larger areas
merged_cell = grid.merge_cells(0, 0, 1, 1) # 2x2 merged area
Row-Based Grid Access
Easily add content to grid rows without specifying exact column indices:
# Create a slide with a 3x3 grid
slide, grid = pres.add_grid_slide(
title="Row-Based Grid Access",
rows=3,
cols=3,
padding=5.0
)
# Add content to the first row using row-level access
# This automatically adds each item to the next available cell in the row
grid[0].add_text(
text="First item in row 0",
font_size=16,
align="center"
)
grid[0].add_text(
text="Second item in row 0",
font_size=16,
align="center"
)
grid[0].add_text(
text="Third item in row 0",
font_size=16,
align="center"
)
# Add content to the second row
grid[1].add_text(
text="First item in row 1",
font_size=16,
align="center"
)
grid[1].add_text(
text="Second item in row 1",
font_size=16,
align="center"
)
Templates
EasyPPTX supports multiple template formats for consistent presentation design.
Reference PowerPoint Templates
Use existing PowerPoint files as templates:
# Create a presentation using an existing template
pres = Presentation(template_path="template.pptx")
# Add a slide with a title
slide = pres.add_slide(title="Presentation with Template")
# Add content to the slide
slide.add_text(
text="Content using the template styles",
x="10%",
y="30%",
width="80%",
height="30%",
font_size=24
)
# Save the presentation
pres.save("output.pptx")
TOML-Based Templates
Create, share, and reuse templates using human-readable TOML files:
from easypptx import Presentation
from easypptx.template import TemplateManager
# Initialize template manager with template directory
tm = TemplateManager(template_dir="templates")
# Load a template from a TOML file
template_name = tm.load("templates/business_title.toml")
# Create a presentation
pres = Presentation()
# Create a slide using the loaded template
slide = pres.add_slide_from_template(template_name)
# Add content to the templated slide
slide.add_text(
text="Quarterly Business Review",
x="10%",
y="30%",
width="80%",
height="20%",
font_size=44,
font_bold=True,
align="center",
color="white"
)
slide.add_text(
text="Q2 2025 Financial Results",
x="10%",
y="55%",
width="80%",
height="10%",
font_size=24,
align="center",
color="#66ccff"
)
# Save the presentation
pres.save("output.pptx")
Sample TOML template (business_title.toml):
# Business Template - Title Slide
bg_color = "#003366" # Dark blue background
[title]
text = "Presentation Title"
position = { x = "10%", y = "30%", width = "80%", height = "20%" }
font = { name = "Meiryo", size = 44, bold = true }
align = "center"
vertical = "middle"
color = "white"
[subtitle]
text = "Subtitle or Presenter Information"
position = { x = "10%", y = "55%", width = "80%", height = "10%" }
font = { name = "Meiryo", size = 24, bold = false }
align = "center"
vertical = "middle"
color = "#66ccff" # Light blue for subtitle
Dark Theme Support
Create modern presentations with dark backgrounds and vibrant colors:
# Create a presentation with black background
pres = Presentation(default_bg_color="black")
# Add a slide with default black background and a title
slide1 = pres.add_slide(
title="Dark Theme Example",
title_color="cyan"
)
# Add high-contrast text directly to the slide
slide1.add_text(
text="High contrast text on dark background",
x="10%",
y="30%",
width="80%",
height="20%",
font_size=24,
color="white"
)
# Add a slide with a custom background color
slide2 = pres.add_slide(
title="Custom Dark Background",
title_color="white",
bg_color=(0, 20, 40) # Dark blue
)
# Add content with vibrant colors
slide2.add_text(
text="Text with vibrant color",
x="10%",
y="30%",
width="80%",
height="20%",
font_size=24,
color="lime"
)
# Add a shape with custom color
slide2.add_shape(
shape_type="ROUNDED_RECTANGLE",
x="30%",
y="60%",
width="40%",
height="15%",
fill_color="purple"
)
# Set background color for an existing slide
slide1.set_background_color("darkgray")
Getting started with development
1. Create a New Repository
First, create a repository on GitHub with the same name as this project, and then run the following commands:
git init -b main
git add .
git commit -m "init commit"
git remote add origin git@github.com:Ameyanagi/EasyPPTX.git
git push -u origin main
2. Set Up Your Development Environment
Then, install the environment and the lefthook git hooks with
make install
This will also generate your uv.lock file. Code quality is enforced with
ruff (lint + format) and ty (type checking); run everything with make check.
3. Run tests
uv run pytest
Project Structure
src/easypptx/- Main packagepresentation.py- Core presentation handling and slide factoriesslide.py- Slide content methods (text, images, shapes, tables, charts)grid.py- Grid layout system for complex arrangementspositioning.py- Shared percentage/inch position arithmeticcommon.py- Shared constants (colors, alignment, fonts) and helperstext.py- Text elements and formattingimage.py- Image handlingtable.py- Table creation from datachart.py- Chart generationpyplot.py- Integration with matplotlib plotstemplate.py- Template management and utilitiestemplate_generator.py- Generating starter TOML templates
examples/- Example scripts, organized by topicbasics/- Quickstart and core featuresgrid/- Grid layout workflow (start with008_quick_slide_deck.py)templates/- Template system exampleslayouts/,styling/,advanced/- Positioning, styling, and advanced usage
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Repository initiated with fpgmaas/cookiecutter-uv.
Release files for EasyPPTX 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| easypptx-0.7.0.tar.gz | 284.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| easypptx-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 411.1 kB
Release files / easypptx-0.7.0.tar.gz
| Download URL | easypptx-0.7.0.tar.gz |
|---|---|
| Size | 284.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
049f8b75b19acdc92b44bca828225011227049c9af3752fee1449993104cd8d6
|
|
BLAKE2b-256 checksum How to use checksums |
e858894035be928d02efaa8758005b2e7eb18e413fe3951edc645e0fd47a41e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / easypptx-0.7.0-py3-none-any.whl
| Download URL | easypptx-0.7.0-py3-none-any.whl |
|---|---|
| Size | 126.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79735ce2a1401505f9b464d184f52aacb3abd4b0f01e98ba2a2accdff32ae07b
|
|
BLAKE2b-256 checksum How to use checksums |
b60b566eaccadbf5f4dde99433b778303bcf27c47172c01cd9629e40369b90cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|