python-pptx: создание презентаций PowerPoint из Python
Библиотека python-pptx: установка через pip install python-pptx, слайды с текстом, картинками, таблицами и диаграммами, чтение готовой презентации.
Содержание · 11 разделов
- Установка python-pptx
- Частые ошибки при установке
- Презентация, макеты и плейсхолдеры
- Размеры: Inches, Pt, Cm
- Текст и форматирование
- Картинки
- Таблицы
- Диаграммы
- Чтение и правка готовой презентации
- Частые ошибки
- AttributeError: ‘NoneType’ object has no attribute ‘text’
- PackageNotFoundError: Package not found at ’…’
- Слайд создан, но текст не виден
- PermissionError при сохранении
- Форматирование пропало после замены текста
- Частые вопросы
- Можно ли сохранить презентацию в PDF или картинки?
- Как отцентрировать картинку на слайде?
- Как удалить пустой плейсхолдер?
- Как скопировать слайд?
- Как отдать презентацию из веб-приложения без сохранения на диск?
- Что делать с ошибкой AttributeError: module ‘collections’ has no attribute …?
- Итог
python-pptx — библиотека для создания и редактирования презентаций PowerPoint (.pptx) из кода на Python. С её помощью отчёты со слайдами, таблицами и диаграммами собираются автоматически, без ручной работы в PowerPoint. Быстрый ответ — установка и первый слайд:
pip install python-pptx
from pptx import Presentation
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[0]) # титульный макет
slide.shapes.title.text = "Отчёт за квартал"
slide.placeholders[1].text = "Подготовлено автоматически на Python"
prs.save("report.pptx")
Обратите внимание: пакет называется python-pptx, а модуль для импорта — pptx. Ниже — установка и типичные ошибки с именем пакета, макеты слайдов, текст и форматирование, картинки, таблицы, диаграммы, чтение готовых файлов. Примеры проверены на python-pptx 1.0.2 и Python 3.12.
Установка python-pptx
Устанавливайте пакет в виртуальное окружение проекта:
# Windows
py -m pip install python-pptx
# macOS / Linux
python3 -m pip install python-pptx
Вместе с ним установятся зависимости: lxml (работа с XML внутри .pptx), Pillow (картинки), XlsxWriter (данные для диаграмм) и typing-extensions. Сам PowerPoint для работы библиотеки не нужен — она пишет файл напрямую, поэтому работает и на Linux-сервере.
Проверка:
import pptx
print(pptx.__version__) # → 1.0.2
Частые ошибки при установке
Запросы «pip install python pptx» и «python pptx install» обычно появляются после одной из этих ошибок:
-
Пробел вместо дефиса. Команда
pip install python pptxпытается поставить два пакета —pythonиpptx— и завершается ошибкой:ERROR: Could not find a version that satisfies the requirement python (from versions: none) ERROR: No matching distribution found for python -
Имя модуля вместо имени пакета.
pip install pptxтоже не сработает:No matching distribution found for pptx. Правильно —pip install python-pptx. -
Неправильный импорт.
import python_pptxдаётModuleNotFoundError: No module named 'python_pptx'. Импортируйтеpptx:from pptx import Presentation. -
Пакет стоит в другом интерпретаторе. Если
ModuleNotFoundError: No module named 'pptx'появляется после успешной установки, pip и скрипт используют разные Python. Запускайте pip какpython -m pipиз того же окружения — подробнее в статье про ModuleNotFoundError и в руководстве по установке библиотек.
Презентация, макеты и плейсхолдеры
Presentation() без аргументов создаёт пустую презентацию на встроенном шаблоне. Presentation("template.pptx") открывает существующий файл — так можно взять корпоративный шаблон с фирменными цветами и шрифтами.
Слайд добавляется по макету (layout). Во встроенном шаблоне их 11:
| Индекс | Макет | Что на слайде |
|---|---|---|
| 0 | Title Slide | заголовок и подзаголовок |
| 1 | Title and Content | заголовок и блок со списком |
| 2 | Section Header | заголовок раздела |
| 3 | Two Content | заголовок и две колонки |
| 5 | Title Only | только заголовок |
| 6 | Blank | пустой слайд |
Список макетов любого шаблона можно вывести так:
for i, layout in enumerate(prs.slide_layouts):
print(i, layout.name)
Плейсхолдеры — заготовленные поля макета. Заголовок доступен как slide.shapes.title, остальные поля — через slide.placeholders[idx]. Пример слайда со списком:
slide = prs.slides.add_slide(prs.slide_layouts[1])
slide.shapes.title.text = "Итоги"
body = slide.placeholders[1].text_frame
body.text = "Выручка выросла на 12%" # первый пункт
p = body.add_paragraph()
p.text = "Новых клиентов: 340"
p = body.add_paragraph()
p.text = "Из них корпоративных: 25"
p.level = 1 # вложенный пункт
Встроенный шаблон имеет формат 4:3 (10 × 7,5 дюйма). Для широкоформатных слайдов 16:9 задайте размер сразу после создания презентации:
from pptx.util import Inches
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
Размеры: Inches, Pt, Cm
Координаты и размеры в .pptx хранятся в единицах EMU (914 400 на дюйм). Вручную их считать не нужно — используйте помощники из pptx.util:
from pptx.util import Inches, Pt, Cm
print(Inches(1), Cm(2), Pt(32)) # → 914400 720000 406400
Позиция фигуры задаётся отступом слева (left) и сверху (top) от левого верхнего угла слайда, затем шириной и высотой.
Текст и форматирование
На пустой слайд текст добавляют текстовым полем. Текст в python-pptx устроен в три уровня: text_frame → абзацы (paragraphs) → фрагменты (runs). Шрифт задаётся у фрагмента, выравнивание — у абзаца:
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
slide = prs.slides.add_slide(prs.slide_layouts[6]) # пустой макет
box = slide.shapes.add_textbox(Inches(1), Inches(1), Inches(8), Inches(1))
tf = box.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER
run = p.add_run()
run.text = "Крупный красный текст"
run.font.size = Pt(32)
run.font.bold = True
run.font.name = "Arial"
run.font.color.rgb = RGBColor(0xC0, 0x00, 0x00)
Фигуры — прямоугольники, стрелки, овалы — добавляет add_shape():
from pptx.enum.shapes import MSO_SHAPE
shape = slide.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(1), Inches(3), Inches(3), Inches(1))
shape.text = "Фигура"
shape.fill.solid()
shape.fill.fore_color.rgb = RGBColor(0x1F, 0x77, 0xB4)
Картинки
add_picture() вставляет PNG, JPEG, GIF и другие растровые форматы. Если указать только ширину, высота подберётся с сохранением пропорций:
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "График"
pic = slide.shapes.add_picture("chart.png", Inches(1), Inches(1.5), width=Inches(8))
Так в презентацию попадают графики, построенные в Matplotlib: сохраните фигуру через fig.savefig("chart.png", dpi=150) и вставьте файл на слайд.
Таблицы
add_table() создаёт таблицу нужного размера, ячейки заполняются через cell(строка, столбец):
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Продажи по городам"
data = [("Город", "Продажи"), ("Москва", "1200"), ("Казань", "800"), ("Пермь", "450")]
rows, cols = len(data), len(data[0])
table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1.5), Inches(8), Inches(2)).table
for r, row in enumerate(data):
for c, value in enumerate(row):
table.cell(r, c).text = value # только строки
table.columns[0].width = Inches(5)
table.columns[1].width = Inches(3)
В ячейку записывается только строка: число вызовет AttributeError: 'int' object has no attribute 'split', поэтому преобразуйте значения через str() или f-строки. Данные для таблицы удобно готовить в pandas — например, перебрать строки DataFrame через df.itertuples().
Диаграммы
В отличие от вставленной картинки, нативная диаграмма PowerPoint остаётся редактируемой: данные можно поменять прямо в PowerPoint.
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE, XL_LEGEND_POSITION
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "Выручка"
chart_data = CategoryChartData()
chart_data.categories = ["Янв", "Фев", "Мар"]
chart_data.add_series("2026", (120, 95, 140))
chart = slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(1), Inches(1.5), Inches(8), Inches(5), chart_data
).chart
chart.has_legend = True
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
chart.legend.include_in_layout = False
Другие типы: XL_CHART_TYPE.LINE, XL_CHART_TYPE.PIE, XL_CHART_TYPE.BAR_CLUSTERED. Несколько рядов данных добавляются повторными вызовами add_series().
Заметки докладчика к слайду:
slide.notes_slide.notes_text_frame.text = "Сказать про сезонность"
prs.save("report.pptx")
Чтение и правка готовой презентации
Чтобы извлечь текст, переберите слайды и фигуры. У таблиц нет text_frame, их проверяют отдельно через has_table:
from pptx import Presentation
prs = Presentation("report.pptx")
for number, slide in enumerate(prs.slides, start=1):
for shape in slide.shapes:
if shape.has_text_frame and shape.text_frame.text:
print(number, shape.text_frame.text)
elif shape.has_table:
for row in shape.table.rows:
print(number, [cell.text for cell in row.cells])
Фрагмент вывода для презентации из примеров выше:
1 Отчёт за квартал
1 Подготовлено автоматически на Python
...
5 Продажи по городам
5 ['Город', 'Продажи']
5 ['Москва', '1200']
Для замены текста в шаблоне меняйте run.text, а не text_frame.text: присваивание text_frame.text удаляет фрагменты вместе с их форматированием.
replacements = {"Отчёт за квартал": "Отчёт за III квартал"}
for slide in prs.slides:
for shape in slide.shapes:
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
for old, new in replacements.items():
if old in run.text:
run.text = run.text.replace(old, new)
prs.save("report_q3.pptx")
PowerPoint иногда разбивает одно слово на несколько фрагментов (например, после проверки орфографии), и тогда метка не найдётся в одном run. Для шаблонов набирайте метки вроде client_name одним действием, без последующей правки.
Частые ошибки
AttributeError: ‘NoneType’ object has no attribute ‘text’
У макета нет заголовка, а код обращается к slide.shapes.title — например, на пустом макете 6 (Blank). Выберите макет с заголовком или добавьте текстовое поле через add_textbox().
PackageNotFoundError: Package not found at ’…’
Библиотека не нашла файл по указанному пути или файл не является .pptx. Проверьте путь (относительный путь считается от текущей папки запуска) и формат: старые презентации .ppt и файлы других типов python-pptx не открывает — сначала сохраните презентацию в PowerPoint как .pptx.
Слайд создан, но текст не виден
Текстовое поле вышло за пределы слайда: координаты больше prs.slide_width или prs.slide_height. Для макета 4:3 ширина — 10 дюймов, для 16:9 — 13,333 дюйма.
PermissionError при сохранении
Файл с тем же именем открыт в PowerPoint, и Windows не даёт его перезаписать. Закройте презентацию или сохраните под другим именем.
Форматирование пропало после замены текста
Использовано shape.text = ... или text_frame.text = ... — они пересоздают абзацы. Меняйте текст на уровне run.text, как в примере выше.
Частые вопросы
Можно ли сохранить презентацию в PDF или картинки?
Средствами python-pptx — нет: библиотека не рисует слайды, а только записывает XML внутри .pptx. Для конвертации нужна программа, которая умеет отображать презентации. На сервере обычно используют LibreOffice в фоновом режиме:
soffice --headless --convert-to pdf report.pptx
На Windows с установленным PowerPoint можно также управлять им через COM-интерфейс (пакет pywin32).
Как отцентрировать картинку на слайде?
Вставьте картинку с нужной шириной, а затем вычислите отступы из размеров слайда и самой картинки:
pic = slide.shapes.add_picture("chart.png", 0, 0, width=Inches(6))
pic.left = (prs.slide_width - pic.width) // 2
pic.top = (prs.slide_height - pic.height) // 2
Для текста по центру используется выравнивание абзаца PP_ALIGN.CENTER из раздела про форматирование.
Как удалить пустой плейсхолдер?
Незаполненный плейсхолдер в режиме показа не виден, но в редакторе PowerPoint остаётся пустой рамкой с подсказкой. Публичного метода удаления нет, поэтому элемент убирают из XML слайда:
for ph in list(slide.placeholders):
if ph.has_text_frame and not ph.text_frame.text:
ph._element.getparent().remove(ph._element)
Атрибут _element — внутренний API библиотеки; проще выбрать макет без лишних полей, например Title Only или Blank.
Как скопировать слайд?
Готового метода копирования слайдов в python-pptx нет. Надёжнее не копировать слайды, а генерировать их заново из данных: подготовьте шаблон .pptx с нужными макетами и создавайте каждый слайд через add_slide() с нужным макетом. Копирование фигур через XML возможно, но картинки и диаграммы сломаются, если вручную не перенести их связи (relationships) с файлами внутри пакета.
Как отдать презентацию из веб-приложения без сохранения на диск?
prs.save() принимает не только путь, но и файловый объект. Сохраните презентацию в io.BytesIO и верните байты в ответе с типом application/vnd.openxmlformats-officedocument.presentationml.presentation:
import io
buf = io.BytesIO()
prs.save(buf)
data = buf.getvalue() # байты готового .pptx
Что делать с ошибкой AttributeError: module ‘collections’ has no attribute …?
Установлена старая версия python-pptx (до 0.6.22), несовместимая с Python 3.10 и новее. Обновите пакет: pip install -U python-pptx.
Итог
Установите пакет командой pip install python-pptx, импортируйте модуль pptx и собирайте презентацию из слайдов по макетам: текст — через плейсхолдеры и add_textbox(), данные — через add_table() и add_chart(), графики — через add_picture(). Генерацию отчётов удобно встроить в сценарии автоматизации на Python. Другие полезные пакеты собраны в обзоре библиотек Python, полный справочник API — в документации python-pptx.
- #Python
- #python-pptx
- #PowerPoint
- #Автоматизация