Презентации в вашем корпоративном шаблоне через Claude Code
Что реально переносится из шаблона в сгенерированный файл, а что нет — и почему у половины шаблонов логотип не переедет никогда.
Нейросети делают презентации, которые видно с порога: стандартный синий #4472C4, шрифт Calibri, все слайды одной композиции. Причина не в модели, а в постановке задачи — её просят придумать оформление, и она придумывает.
Рабочий подход обратный: нейросеть отдаёт только содержание, а оформление берётся из настоящего файла PowerPoint. Тогда результат выглядит как остальные презентации компании, а не как продукт генератора.
Ниже — что при этом действительно переносится, а что нет. Проверено на пяти разных шаблонах, включая корпоративные и скачанные с фотостоков.
Что лежит внутри .pptx
Файл .pptx — это ZIP-архив с XML внутри. Переименуйте копию в .zip и распакуйте:
ppt/presentation.xml размер листа, список слайдов
ppt/slides/slide1.xml содержимое первого слайда
ppt/slideLayouts/ макеты
ppt/slideMasters/ мастера
ppt/theme/theme1.xml тема: палитра и шрифты
ppt/media/ картинкиЗдесь и кроется первая ловушка.
Тема почти всегда врёт
Логично взять цвета и шрифты из theme1.xml — там они и лежат. На практике в теме почти всегда стандартная офисная палитра: тот самый синий #4472C4 и Calibri. Дизайнер красил фигуры вручную и тему не трогал.
Читать нужно сами слайды: посчитать, какие цвета и кегли встречаются чаще всего в ppt/slides/*.xml. Это и есть фактическое оформление.
import collections, re, zipfile
z = zipfile.ZipFile("shablon.pptx")
tsveta, kegli = collections.Counter(), collections.Counter()
for n in z.namelist():
if not re.match(r"ppt/slides/slide\d+\.xml$", n):
continue
raw = z.read(n).decode("utf-8", "replace")
for m in re.finditer(r'srgbClr val="([0-9A-Fa-f]{6})"', raw):
tsveta[m.group(1).upper()] += 1
for m in re.finditer(r'\bsz="(\d+)"', raw):
k = int(m.group(1)) / 100
if 6 <= k <= 96:
kegli[k] += 1
print("цвета:", tsveta.most_common(8))
print("кегли:", kegli.most_common(8))Самый частый крупный кегль — размер заголовка. От него потом считается вся шкала: подзаголовок, основной текст, подписи.
Акцентный цвет: не самый частый
Наивный подход — взять самый частый цвет — даёт чёрный или белый. Нужен самый насыщенный из часто встречающихся:
def nasyshchennost(hx):
r, g, b = (int(hx[i:i+2], 16) for i in (0, 2, 4))
return max(r, g, b) - min(r, g, b)
MARKERY = {"FFFF00", "00FF00", "FF0000", "00FFFF", "FF00FF"}
kandidaty = [(c, k) for c, k in tsveta.most_common(12)
if k >= 2 and c not in MARKERY and nasyshchennost(c) > 40]
aktsent = max(kandidaty, key=lambda ck: nasyshchennost(ck[0]) * ck[1])[0]Исключение маркеров обязательно. Без него на документах с выделениями текста акцентом становится #FFFF00 — жёлтый маркер.
Логотип: переносится не из всякого шаблона
Здесь главное, что стоит проверить до начала работы.
Фирменная графика — подложки, логотип, колонтитулы — живёт в макетах (slideLayouts) и мастерах (slideMasters). Если открыть сам шаблон и добавлять слайды на его макетах, вся эта графика приходит сама: она наследуется, а не копируется.
from pptx import Presentation
prs = Presentation("shablon.pptx")
# убрать слайды шаблона, сохранив мастера, макеты и тему
lst = prs.slides._sldIdLst
for sid in list(lst):
prs.part.drop_rel(sid.rId)
lst.remove(sid)
# новые слайды на макете шаблона — логотип придёт сам
sl = prs.slides.add_slide(prs.slide_layouts[0])Но так устроены не все шаблоны. Скачанные с фотостоков — Slidesgo, Canva, Envato — часто имеют пустые макеты, а весь дизайн нарисован прямо на слайдах. Из такого брать нечего.
Проверить можно за секунду: посчитать фигуры в макетах.
def est_grafika(put):
prs = Presentation(put)
for m in prs.slide_masters:
for L in m.slide_layouts:
svoi = [sh for sh in L.shapes if not sh.is_placeholder]
if svoi:
return True
return FalseНа проверенных шаблонах: корпоративный ЛУКОЙЛа — графика в макетах есть, логотип и красные полосы переносятся. «Bold Isometric SEO» с фотостока — одиннадцать макетов, все пустые, 66 изображений лежат на слайдах. Из него перейдут только шрифт, цвета и пропорции листа.
Шрифт, которого нет
Вторая частая беда. Шаблон набран Montserrat или Public Sans, а на компьютере их нет — PowerPoint молча подставит свой, и вёрстка разъедется.
Проверять до работы:
import os, re, sys
from pathlib import Path
def ustanovlen(imya):
papki = ([Path("/System/Library/Fonts"), Path("/Library/Fonts"),
Path.home() / "Library/Fonts"] if sys.platform == "darwin"
else [Path(os.environ.get("WINDIR", "C:/Windows")) / "Fonts"])
cel = re.sub(r"[^a-z0-9]", "", imya.lower())
for p in papki:
if not p.is_dir():
continue
for koren, _, fajly in os.walk(p):
for f in fajly:
if f.lower().endswith((".ttf", ".otf", ".ttc")):
if cel in re.sub(r"[^a-z0-9]", "", f.lower()):
return True
return FalseОтдельная тонкость: сравнивать надо по семейству, а не по начертанию. «Montserrat Black» — это Montserrat, а не второй шрифт. Без этого приличный шаблон выглядит кашей из пяти гарнитур.
Поля берутся из макета, а не из головы
Если макет занимает треть листа цветной плашкой, текст по стандартным координатам ляжет поверх неё. Свободное поле нужно считать.
Надёжно определить его геометрией сложнее, чем кажется: крупный прямоугольник чаще оказывается холстом, на котором и надо писать, а не препятствием. Практичное правило — сужать поле только под узкие полосы, прижатые к краю, а для содержательных слайдов брать наименее разрисованный макет. Логотип при этом всё равно придёт из мастера.
Отдельно стоит смотреть кромки: колонтитул складывается из мелочи — кружок логотипа, набор букв, номер страницы. Поодиночке каждая фигура ниже любого порога, а вместе они занимают полосу ровно там, где ставят сноски.
Проверка, которую нельзя пропустить
Расчёт координат слеп к тому, как текст лёг на самом деле. Все ошибки вёрстки, которые встретились на практике, нашлись только на картинке:
- заголовок в 90 pt посчитался в одну строку, а отрисовался в две и наехал
на подзаголовок;
- подпись легла на нижний колонтитул с логотипом;
- белый текст на светлой части фотографии пропал целиком.
Рендерить так:
soffice --headless --convert-to pdf gotovaya.pptx
pdftoppm -jpeg -r 110 gotovaya.pdf slideИ посмотреть каждый файл. Это тридцать секунд, и они отменяют половину правок.
Что запомнить
Тема файла врёт — читайте сами слайды. Логотип переносится только из шаблонов с непустыми макетами, и это проверяется до начала работы. Шрифт сверяйте с тем, что стоит на машине, иначе предпросмотр покажет не то, что увидит получатель. И обязательно смотрите на отрендеренные слайды — расчёт координат их не заменяет.