Создание слайдов и диаграмм с python-pptx

Раздел: Офис -> создание презентаций

Библиотека python-pptx позволяет создавать и изменять презентации PowerPoint программно. Установка выполняется командой:

pip install python-pptx

Python pptx (библиотека python-pptx)

После установки импортируются основные классы: Presentation, SlideLayout, Slide и другие.

Основные приёмы работы с python-pptx

Базовое создание презентации

Ниже приведён минимальный код, который создаёт презентацию, добавляет один слайд с заголовком и текстом, затем сохраняет файл.


from pptx import Presentation
from pptx.util import Inches

prs = Presentation()
slide_layout = prs.slide_layouts[1]  # макет с заголовком и текстом
slide = prs.slides.add_slide(slide_layout)
title = slide.shapes.title
content = slide.placeholders[1]

title.text = "Заголовок слайда"
content.text = "Текст содержимого"

prs.save("example.pptx")

Пояснение шагов:

  • Presentation() создаёт пустую презентацию с настройками по умолчанию.
  • slide_layouts[1] выбирает второй макет (индекс 0 обычно титульный слайд).
  • add_slide добавляет слайд на основе выбранного макета.
  • slide.shapes.title обращается к placeholder заголовка.
  • slide.placeholders[1] обращается к placeholder для текста (индекс может отличаться).
  • prs.save сохраняет файл.

Типичные проблемы:

  • Русские символы отображаются некорректно. Решение: явно указать шрифт, поддерживающий кириллицу, например 'Arial'. Шрифт задаётся через объект run.
  • Размеры в EMU. В python-pptx все размеры задаются в EMU (English Metric Units). Для удобства используются функции Inches, Cm или Pt из pptx.util.
  • Placeholders недоступны. Если макет не содержит нужного placeholder, обращение вызовет ошибку. Рекомендуется проверять наличие slide.placeholders или использовать slide.shapes.title только если заголовок существует.

Как добавить слайд с конкретным макетом?

Макеты слайдов определяют расположение placeholder'ов. Чтобы выбрать нужный макет, можно перебирать slide_layouts по индексу или имени. Имена макетов доступны через slide_layout.name.


from pptx import Presentation
prs = Presentation()
# Вывод доступных макетов
for i, layout in enumerate(prs.slide_layouts):
    print(i, layout.name)
# Добавление слайда с макетом "Blank" (обычно индекс 6)
slide_layout = prs.slide_layouts[6]  # пустой слайд
slide = prs.slides.add_slide(slide_layout)
prs.save("blank_slide.pptx")

Пояснение:

Каждая презентация содержит набор макетов из темы оформления. Индексы могут различаться в зависимости от версии PowerPoint. Рекомендуется выводить имена макетов для выбора.

Проблема:

При загрузке презентации из шаблона макеты могут отсутствовать или быть переопределены. Решение: открыть шаблон и проверить макеты перед использованием.

Как добавить текст с различным форматированием?

Для форматирования текста используется объект Paragraph и Run. Каждый run имеет свой шрифт, размер, цвет и т.д.


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

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[1])
text_frame = slide.placeholders[1].text_frame
text_frame.clear()  # очистить стандартный текст

p = text_frame.paragraphs[0]
run = p.add_run()
run.text = "Жирный красный текст"
run.font.bold = True
run.font.color.rgb = RGBColor(0xFF, 0x00, 0x00)
run.font.size = Pt(24)

p2 = text_frame.add_paragraph()
run2 = p2.add_run()
run2.text = "Курсивный синий"
run2.font.italic = True
run2.font.color.rgb = RGBColor(0x00, 0x00, 0xFF)

prs.save("formatted_text.pptx")

Пояснение:

Метод add_run добавляет фрагмент текста с единым стилем. font объект позволяет задать параметры. Для русского текста необходимо явно указать шрифт через run.font.name = 'Arial'.

Типичные ошибки:

  • Игнорирование смены шрифта приводит к отображению квадратов вместо букв. Рекомендуется всегда указывать run.font.name для кириллицы.
  • Попытка форматировать paragraph.text напрямую не даст эффекта. Только через add_run.

Как вставить изображение в слайд?

Изображения добавляются с помощью slide.shapes.add_picture. Формат поддерживает PNG, JPEG, GIF и другие.


from pptx import Presentation
from pptx.util import Inches

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])  # пустой слайд
img_path = "my_image.png"
# Вставка изображения с координатами (левый верхний угол) и размером
slide.shapes.add_picture(img_path, Inches(1), Inches(1), width=Inches(3), height=Inches(2))
prs.save("image.pptx")

Пояснение:

Параметры left и top задают отступ слева и сверху, width и height размер изображения. Если размеры не указаны, используется оригинальный размер. Если указать только ширину, высота будет масштабирована пропорционально.

Проблема:

Изображение может выйти за границы слайда. Следует проверять размеры. Стандартный слайд имеет ширину 10 дюймов (25,4 см) и высоту 7,5 дюймов (19,05 см).

Как создать таблицу на слайде?

Таблицы добавляются методом slide.shapes.add_table. Возвращается объект Table, через который заполняются ячейки.


from pptx import Presentation
from pptx.util import Inches

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
rows, cols = 3, 4
table_shape = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3))
table = table_shape.table
# Заполнение заголовков
table.cell(0,0).text = "Имя"
table.cell(0,1).text = "Возраст"
table.cell(0,2).text = "Город"
table.cell(0,3).text = "Телефон"
# Заполнение данных
data = [
    ("Анна", 25, "Москва", "123-45-67"),
    ("Иван", 30, "Санкт-Петербург", "987-65-43")
]
for r, row_data in enumerate(data, start=1):
    for c, val in enumerate(row_data):
        table.cell(r, c).text = str(val)
prs.save("table.pptx")

Пояснение:

Первый аргумент add_table - количество строк, второй - столбцов. Размеры таблицы задаются через left, top, width, height. Ячейки индексируются с (0,0). Для форматирования ячеек можно использовать table.cell(r,c).font и table.cell(r,c).fill.

Типичные ошибки:

  • Игнорирование границ - по умолчанию границы ячеек тонкие невидимые. Для отображения границ нужно задать table.cell(r,c).fill.solid() или использовать стили таблицы PowerPoint через table.style.
  • Вставка слишком большого количества данных может привести к переполнению слайда. Рекомендуется автоматически корректировать размеры ячеек или шрифт.

Общие рекомендации:

Для избежания проблем с русскими шрифтами в тексте рекомендуется устанавливать font.name = 'Arial' для каждого run. Для работы с размерами используйте Inches, Cm или Pt из pptx.util. Для проверки наличия placeholder'ов перед обращением - if slide.placeholders: ....

Расширенные сценарии автоматизации

Создание столбчатой диаграммы на основе данных

Для добавления диаграммы используется метод slide.shapes.add_chart. Поддерживаются типы XL_CHART_TYPE.COLUMN_CLUSTERED и другие.

Пример

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

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])

chart_data = CategoryChartData()
chart_data.categories = ['Q1', 'Q2', 'Q3', 'Q4']
chart_data.add_series('Продажи (тыс.)', (120, 150, 130, 200))

chart_frame = slide.shapes.add_chart(
    XL_CHART_TYPE.COLUMN_CLUSTERED,
    Inches(1), Inches(1), Inches(8), Inches(5),
    chart_data
)
chart = chart_frame.chart
chart.has_legend = True
chart.legend.include_in_layout = False

prs.save("chart.pptx")

Результат:

Создаётся файл chart.pptx с одним слайдом, содержащим столбчатую диаграмму с четырьмя кварталами и одним рядом данных.

Пояснение:

CategoryChartData используется для диаграмм с категориями. Метод add_series принимает имя ряда и кортеж значений. add_chart возвращает ChartFrame, который содержит объект chart для дальнейшей настройки (легенда, оси, цвета).

Проблемы:

  • Для сложных диаграмм (с несколькими рядами, разными типами) может потребоваться ChartData другого типа.
  • Цвета столбцов по умолчанию берутся из темы. Изменение цвета: chart.series[0].format.fill.solid() с указанием цвета.

Автоматическое создание слайдов из данных

Данный пример создаёт слайд для каждого элемента списка, добавляя заголовок, изображение и таблицу.

Пример

from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

employees = [
    {'name': 'Анна Иванова', 'position': 'Менеджер', 'photo': 'anna.jpg', 'skills': ['Python', 'Excel']},
    {'name': 'Пётр Петров', 'position': 'Аналитик', 'photo': 'petr.jpg', 'skills': ['SQL', 'Power BI']}
]

for emp in employees:
    slide_layout = prs.slide_layouts[1]  # макет с заголовком и текстом
    slide = prs.slides.add_slide(slide_layout)
    # заголовок
    title = slide.shapes.title
    title.text = emp['name']
    # фото
    if emp.get('photo'):
        slide.shapes.add_picture(emp['photo'], Inches(0.5), Inches(1.5), width=Inches(2), height=Inches(2))
    # список навыков
    text_frame = slide.placeholders[1].text_frame
    text_frame.clear()
    p = text_frame.paragraphs[0]
    run = p.add_run()
    run.text = f"Должность: {emp['position']}"
    run.font.size = Pt(16)
    p2 = text_frame.add_paragraph()
    run2 = p2.add_run()
    run2.text = "Навыки: " + ", ".join(emp['skills'])
    run2.font.size = Pt(14)

prs.save("employees.pptx")

Результат:

Файл employees.pptx содержит два слайда: первый с информацией об Анне, второй о Петре. На каждом слайде есть заголовок, фото (если файл существует) и текстовая информация.

Пояснение:

Цикл по списку словарей позволяет динамически создавать слайды. Важно проверять наличие файлов изображений, чтобы избежать ошибок. Предусмотрен вариант emp.get('photo').

Ошибка:

Если файл изображения отсутствует, возникнет исключение. Решение: обернуть add_picture в try-except или предварительно проверять os.path.exists.

Добавление заметок к слайду

Заметки докладчика добавляются через свойство slide.notes_slide. Если заметки ещё не созданы, их нужно инициализировать.

Пример

from pptx import Presentation

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[1])
# Создание заметок
notes_slide = slide.notes_slide
text_frame = notes_slide.notes_text_frame
text_frame.text = "Это заметки к первому слайду. Здесь можно указать дополнительные пояснения."

# Добавление второго слайда с заметками
slide2 = prs.slides.add_slide(prs.slide_layouts[1])
notes_slide2 = slide2.notes_slide
notes_slide2.notes_text_frame.text = "Заметки для второго слайда.\nПодробный комментарий."

prs.save("notes.pptx")

Результат:

В файле notes.pptx каждый слайд содержит заметки, которые видны в режиме докладчика.

Пояснение:

slide.notes_slide возвращает объект NotesSlide. Если заметки не были добавлены ранее, этот атрибут может отсутствовать (возвращается None). Поэтому перед обращением рекомендуется проверить if slide.has_notes_slide: или создать принудительно через slide.notes_slide (он создаст объект, если его нет).

Проблема:

В некоторых версиях python-pptx атрибут notes_slide может вести себя нестабильно. Рекомендуется использовать slide.notes_slide именно для чтения/записи, а для создания - добавить пустую заметку через slide.notes_slide (он автоматически создаст).

библиотека python-pptx - comments

En
Python pptx (python)