文章目录
PPTX文件本质:一个压缩包
PPTX文件实际上是一个遵循Open XML标准的ZIP压缩包,包含多个XML文件和其他资源。我们可以通过解压工具查看其内部结构:
pptx文件
├── [Content_Types].xml
├── _rels/
├── docProps/
│ ├── app.xml
│ ├── core.xml
│ └── thumbnail.jpeg
└── ppt/
├── presentation.xml
├── slides/
│ ├── slide1.xml
│ ├── slide2.xml
│ └── ...
├── slideLayouts/
├── slideMasters/
├── media/ # 存放图片等媒体资源
├── theme/
└── _rels/
可以看到,每一页幻灯片是一个独立的xml文件
而图片,可能以链接
核心文件解析
1. 幻灯片内容文件 (ppt/slides/slideX.xml)
每个幻灯片对应一个XML文件,包含以下关键结构:
<p:sld>
<p:cSld> <!-- 幻灯片画布 -->
<p:spTree> <!-- 形状树 -->
<p:sp> <!-- 形状/文本框 -->
<p:nvSpPr> <!-- 非可视属性 -->
<p:spPr> <!-- 形状属性 -->
<p:txBody> <!-- 文本内容 -->
</p:sp>
<p:pic> <!-- 图片元素 -->
<p:nvPicPr>
<p:blipFill> <!-- 图片填充 -->
<p:spPr>
</p:pic>
</p:spTree>
</p:cSld>
</p:sld>
2. 元素类型解析
文本框元素 (p:sp)
<p:sp>
<p:nvSpPr>
<p:cNvPr id="1" name="TextBox 1"/>
<p:cNvSpPr/>
</p:nvSpPr>
<p:spPr> <!-- 样式属性 -->
<a:xfrm> <!-- 位置/尺寸 -->
<a:off x="1524000" y="1524000"/>
<a:ext cx="2743200" cy="914400"/>
</a:xfrm>
<a:prstGeom prst="rect"> <!-- 预设形状 -->
<a:avLst/>
</a:prstGeom>
</p:spPr>
<p:txBody> <!-- 文本内容 -->
<a:bodyPr/>
<a:p> <!-- 段落 -->
<a:r> <!-- 文本运行 -->
<a:rPr lang="zh-CN" sz="1800"/> <!-- 文本属性 -->
<a:t>Hello World</a:t> <!-- 文本内容 -->
</a:r>
</a:p>
</p:txBody>
</p:sp>
图片元素 (p:pic)
<p:pic>
<p:nvPicPr>
<p:cNvPr id="2" name="Picture 1"/>
<p:cNvPicPr>
<a:picLocks noChangeAspect="1"/>
</p:cNvPicPr>
</p:nvPicPr>
<p:blipFill> <!-- 图片填充 -->
<a:blip r:embed="rId1"/> <!-- 引用关系ID -->
<a:stretch>
<a:fillRect/>
</a:stretch>
</p:blipFill>
<p:spPr> <!-- 样式属性 -->
<a:xfrm>
<a:off x="1524000" y="1524000"/>
<a:ext cx="2743200" cy="1828800"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</p:spPr>
</p:pic>
单位系统
PPTX中使用EMU(English Metric Unit)作为基本单位:
- 1英寸 = 914400 EMU
- 1厘米 = 360000 EMU
- 1磅 = 12700 EMU
转换公式:
function emuToPx(emu, dpi = 96) {
return Math.round((emu / 914400) * dpi);
}
开发注意事项
- 关系映射:所有资源引用都通过
ppt/_rels
目录下的关系文件映射 - 媒体资源:图片存储在
ppt/media
目录,通过r:embed
引用 - 样式继承:幻灯片会继承slideMaster和slideLayout中的样式
- 命名空间:XML中使用大量命名空间前缀,解析时需注意
参考工具
下期预告:如何在前端实现PPTX的页面元素解析与渲染
pptx渲染路线图
在此,我们简单确定一个渲染路线图, 后续按照此顺序对 每一页的元素完成解析并进行还原度评估