Презентация PowerPoint – это набор слайдов. Каждый слайд – холст с текстовыми полями, фигурами, картинками, таблицами и диаграммами. Есть и всякие продвинутые штуки вроде анимаций, SmartArt и видео, но для 90% рабочих слайдов они не нужны.
Файл PowerPoint – место, где весь этот контент хранится так, чтобы его мог прочитать компьютер. Внутри лежит и текст, который вы набрали для заголовка диаграммы, и встроенные файлы Excel с данными для этой диаграммы, и .png-файлы с логотипом вашей компании, и свойства, которые определяют, как всё это отрисуется на экране: размер шрифта заголовка, цвет подписей данных, высота строк таблицы, показывать ли сетку на диаграмме.
Ниже понятным языком разберём, как устроен самый популярный в мире формат презентаций.
Как файл хранит всю информацию?
Можно попробовать записать всё в текстовый файл. Перечислить каждый элемент и его свойства. Вот примитивный пример: пустой слайд с единственным текстовым полем, где написано «Hello world!».

Можно открыть «Блокнот» и набрать .txt-файл примерно такого вида:
Слайд 1 - Ширина = 13.33 дюйма - Высота = 7.5 дюйма - Фон = белый - Текстовый блок 1 - Текст = "Hello world!" - Семейство шрифтов = Arial - Размер шрифта = 18 - Цвет шрифта = чёрный - Позиция = 5.9 дюйма от левого края, 3.5 дюйма от верхнего края
Допустим, вы добавляете ещё один простенький слайд.

В .txt-файл добавится вот это:
Слайд 2 - Ширина = 13.33 дюйма - Высота = 7.5 дюйма - Фон = белый - Текстовый блок 1 - Текст = "This is a circle" - Семейство шрифтов = Arial - Размер шрифта = 18 - Цвет шрифта = чёрный - Позиция = 5.9 дюйма от левого края, 2 дюйма от верхнего края - Фигура 1 - Тип фигуры = круг - Заливка = красная - Высота = 2 дюйма - Ширина = 2 дюйма - Позиция = 5.7 дюйма от левого края, 2.75 дюйма от верхнего края
Смотрите вы на это и думаете: «Хм, я переписываю одни и те же свойства. У всех слайдов одинаковая ширина и высота, да и шрифт я собираюсь использовать однотипный. Дай-ка соберу всё это в одном месте».
Презентация - Ширина слайда = 13.33 дюйма - Высота слайда = 7.5 дюйма - Фон = белый - Цвет шрифта = чёрный - Семейство шрифтов = Arial - Размер шрифта = 18 Слайд 1 - Текстовый блок 1 - Текст = "Hello world!" - Позиция = 5.9 дюйма от левого края, 3.5 дюйма от верхнего края Слайд 2 - Текстовый блок 1 - Текст = "This is a circle" - Позиция = 5.9 дюйма от левого края, 2 дюйма от верхнего края - Фигура 1 - Тип фигуры = круг - Заливка = красная - Высота = 2 дюйма - Ширина = 2 дюйма - Позиция = 5.7 дюйма от левого края, 2.75 дюйма от верхнего края
Так лучше. Но когда у вас будет нормальная колода на 30 страниц, файл раздуется до огромных размеров. Поэтому вы решаете разбить его на файлы поменьше и разложить по папкам.
presentation/ ├── presentation_properties.txt └── slides/ ├── slide1.txt └── slide2.txt
Диаграммы и картинки
Пока что на ваших слайдах живут только текст и фигуры. А как быть с логотипом компании?
Раз вы уже работаете с папками, просто добавьте папку pictures и складывайте туда .png- и .jpg-файлы.
presentation/ ├── presentation_properties.txt ├── slides/ │ ├── slide1.txt │ └── slide2.txt └── pictures/ └── logo.png
А в слайде вы просто ссылаетесь на файл картинки и указываете её размер и положение.
Приятный бонус такого подхода: если вы используете один и тот же логотип на нескольких слайдах, копию картинки для каждого из них хранить не нужно.
Слайд 3 - Картинка - Источник = logo.png - Высота = 7.5 дюйма - Ширина = 7.5 дюйма - Позиция = 2.92 дюйма от левого края, 0 дюймов от верхнего края

Ту же идею можно применить и к диаграммам. Файлы Excel удобны для хранения числовых данных, так что, вместо того чтобы изобретать велосипед, вы выделяете каждой диаграмме свой .xlsx-файл под её данные.
presentation/ ├── presentation_properties.txt ├── slides/ │ ├── slide1.txt │ ├── slide2.txt │ └── slide3.txt ├── pictures/ │ └── logo.png └── excel/ └── book1.xlsx

Затем при описании диаграммы вы не забываете сослаться на этот файл:
Слайд 4 - Диаграмма - Источник = book1.xlsx - Высота = 6 дюймов - Ширина = 9 дюймов - Позиция = 2.17 дюйма от левого края, 0.75 дюйма от верхнего края - Заголовок = Chart Title - Показывать сетку = true - Максимум оси = 6 - Шаг оси = 1 . . . - Заливка ряда 3 = серая
Эти три точки делают очень много работы. У диаграмм очень много свойств. Можно сделать жирной одну-единственную букву в подписи данных, можно сделать линию горизонтальной оси толще.
Скорее всего, у вас будут слайды с несколькими диаграммами, так что ради собственного душевного спокойствия вы решаете вынести диаграммы в отдельные файлы и применить ту же стратегию ссылок, что и для картинок с файлами Excel.
Вы переносите свойства диаграммы в отдельный файл chart1.txt и упрощаете slide4.txt до:
Слайд 4 - Диаграмма - Источник = chart1.txt - Высота = 6 дюймов - Ширина = 9 дюймов - Позиция = 2.17 дюйма от левого края, 0.75 дюйма от верхнего края
В итоге финальная папка выглядит примерно так:
presentation/ ├── presentation_properties.txt ├── slides/ │ ├── slide1.txt │ ├── slide2.txt │ ├── slide3.txt │ └── slide4.txt ├── pictures/ │ └── logo.png ├── excel/ │ └── book1.xlsx └── charts/ └── chart1.txt
Поздравляю! Вы воссоздали базовую архитектуру .pptx-файлов.
Под капотом .pptx-файл – это ZIP-архив, содержащий множество отдельных файлов. И вместо нашего самодельного .txt-формата в нём используется структурированный текст в формате XML.
Попробуйте переименовать один из своих файлов PowerPoint из .pptx в .zip и убедитесь сами.

А вот что внутри папки slides:

Мы не затронули макеты (layouts) и образцы слайдов (masters), но ваши папки ложатся на реальную структуру один в один, если переименовать «excel» в «embeddings», а «pictures» – в «media».
Чем XML отличается от нашего простого текста?
Давайте-ка распакуем фрагмент того самого slide1.xml, где хранится ваш простенький пример «Hello world!».
<p:cSld> <p:spTree> <p:sp> <p:nvSpPr> <p:cNvPr id="5" name="TextBox 4"> <a:extLst>...</a:extLst> </p:cNvPr> <p:cNvSpPr txBox="1"/> </p:nvSpPr> <p:spPr> <a:xfrm> <a:off x="5359675" y="3244334"/> <a:ext cx="1472650" cy="369332"/> </a:xfrm> <a:prstGeom prst="rect"> <a:avLst/> </a:prstGeom> <a:noFill/> </p:spPr> <p:txBody> <a:bodyPr wrap="square" rtlCol="0"> <a:spAutoFit/> </a:bodyPr> <a:lstStyle/> <a:p> <a:pPr algn="ctr"/> <a:r> <a:rPr lang="en-US" dirty="0"/> <a:t>Hello world!</a:t> </a:r> </a:p> </p:txBody> </p:sp> </p:spTree> </p:cSld>
Нечитаемая машинная каша. Становится чуть лучше, если заменить сокращения на нормальные слова:
<CommonSlideData> <ShapeTree> <Shape> <NonVisualShapeProperties> <NonVisualDrawingProperties id="5" name="TextBox 4"> <ExtensionList>...</ExtensionList> </NonVisualDrawingProperties> <NonVisualShapeDrawingProperties isTextBox="1"/> </NonVisualShapeProperties> <ShapeProperties> <Transform> <Offset x="5359675" y="3244334"/> <Extents width="1472650" height="369332"/> </Transform> <PresetGeometry shape="rectangle"> <AdjustValues/> </PresetGeometry> <NoFill/> </ShapeProperties> <TextBody> <BodyProperties wrap="square" rightToLeftColumns="0"> <ShapeAutoFit/> </BodyProperties> <ListStyle/> <Paragraph> <ParagraphProperties alignment="center"/> <Run> <RunProperties language="en-US" dirty="0"/> <Text>Hello world!</Text> </Run> </Paragraph> </TextBody> </Shape> </ShapeTree> </CommonSlideData>
А если убрать XML-обвязку и менее важные атрибуты, получится что-то вроде:
Слайд - Фигуры - TextBox 4 - Координата X: 5 359 675 - Координата Y: 3 244 334 - Высота: 369 332 - Ширина: 1 472 650 - Preset Geometry: прямоугольник - Без заливки - Текст: Hello world!
Похоже на ваш исходный .txt-файл! Числа для позиции и размера указаны не в дюймах, а в единицах под названием EMU – English Metric Unit. Они огромные – это для того, чтобы обходиться без чисел с плавающей точкой и работать только с целыми числами.
Размера шрифта 18 и шрифта Arial здесь нет, но вы этого и ожидали. Шрифты и их размеры вы записали в presentation_properties.txt, чтобы не повторять их для каждого текстового блока.
В настоящем .pptx-файле семейства шрифтов темы могут жить в theme1.xml в папке theme:
<a:fontScheme name="Office"> <a:majorFont> <a:latin typeface="Arial"/> </a:majorFont> <a:minorFont> <a:latin typeface="Arial"/> </a:minorFont> </a:fontScheme>
То есть по сути .pptx-файл – это набор XML-файлов с данными презентации. Есть папка с отдельными файлами под каждый слайд. И есть ещё несколько XML-файлов под общие свойства вроде шрифтов, которые пришлось бы повторять снова и снова.
Значит, редактировать PPTX легко?
Звучит-то вроде просто. Выдай каждому слайду отдельный файл со списком его свойств, но сделай это эффективно, храня часто используемые свойства в общем месте.
Общая идея здравая, но вот реализация – невероятно грязная.
В 2005 году, под давлением правительств, требовавших открытых стандартов для документов, Microsoft подала форматы OOXML (Office Open XML) на стандартизацию в Ecma International. Ecma опубликовала стандарт в 2006 году, а в 2008-м он был принят как международный стандарт ISO.

Основной документ насчитывает больше 5000 страниц. Это как 4 полные трилогии «Властелина колец». Если распечатать его на одной стороне листа, стопка бумаги получится высотой около 50 см.
Кажется чересчур?
The Document Foundation (создатели LibreOffice – свободной альтернативы Microsoft Office) считает это намеренной уловкой Microsoft, чтобы намертво привязать пользователей к своей экосистеме:
К сожалению, XML-схема может быть как простой, так и излишне сложной, раздутой, запутанной и трудной в реализации без специального знания её особенностей.
Эта искусственная сложность проявляется в глубоко вложенной структуре тегов с избыточной абстракцией, в десятках и даже сотнях необязательных или перегруженных элементов, в неинтуитивных соглашениях об именовании, в повсеместном использовании точек расширения и подстановочных символов, в множественном импорте пространств имён и иерархий типов, а также в скудной или невнятной документации.
Теория приятная. Так и представляешь, как Билл Гейтс звонит Стиву Балмеру:
— Стив, мне нужны самые злобные инженеры, каких только сможешь найти. Пришли мне команду, которая работала над Clippy и Windows Update. Я хочу, чтобы наш Office был недоступен ни одному конкуренту.
— Без проблем, сниму их с проекта Vista и отправлю к тебе.
Это, безусловно, объяснило бы кучу странных решений в OOXML.
Есть и другая, менее приятная теория. PowerPoint создали в 1987 году, а на Windows он вышел в 1990-м. Инженеры тех лет никак не могли знать, чем PowerPoint станет и что ему в итоге придётся уметь. Учитель естествознания в средней школе использует его, чтобы читать лекции с анимациями. А инвестиционные банкиры на том же софте готовят материалы для заседания совета директоров, где одобряют слияние публичных компаний на миллиарды долларов.
Легко критиковать архитектуру 40 лет спустя, задним умом и с накопленным багажом знаний в разработке ПО. Самому OOXML всего около 20 лет, но ему пришлось описать десятилетия функций PowerPoint и уже существующие презентации. Вполне возможно, что OOXML – такой же бардак, как и любая 40-летняя кодовая база. Просто у обычного кода этот хаос спрятан внутри, а формат файла ломать нельзя: старые презентации должны открываться всегда. Поэтому все накопленные за десятилетия костыли ради совместимости и фичи, прикрученные сбоку, никуда не делись, а застыли в спецификации.
Заключение
Файл PowerPoint – это ZIP-архив, содержащий XML-файлы и бинарные ресурсы. В нём хранятся все свойства, которые вы задали в презентации PowerPoint, и он пытается разложить их по отдельным файлам, чтобы избежать повторов и упростить поиск нужного.
Увы, реализация – это минное поле из цепочек наследования, строгого порядка элементов, значений по умолчанию, задаваемых самим приложением, и прочих странных причуд. Именно из-за этого минного поля так сложно автоматизировать PowerPoint кодом. А значит, именно поэтому ИИ-агенты спотыкаются на, казалось бы, элементарных правках.

