1.前言
大家好,我是 Canmick。前些天老板给我安排了个活,要求在 Web 端以幻灯片形式演示 PPT,还要支持动画,一脸茫然的我回了个"👌"。
那么能够实现吗?答案是可以的,业界有较多成熟的方案,比如阿里的 WebOffice,其大概流程是先上传 PPT 文件到服务端,服务端将 PPT 文件转换为 Web 端可读取的格式(假设叫 alippt),前端使用配套的 sdk 加载 alippt 进行演示。

有了大概思路,我们分析下如何实现一套 PPT 解析及演示服务
2.浅析 PPT 格式
要想解析 PPT 得先知道 PPT 的格式规范 ,常见的格式一般有.ppt 或 .pptx
2.1 .ppt 格式
最早的 PPT 文件格式是基于二进制的文件格式,这种格式从 Office 97 开始一直沿用到 Office 2003。它是一个复杂的二进制结构,解析起来相对困难,需要深入了解其内部结构才能进行操作,故本文暂不做探讨。
2.2 .pptx 格式
从 Office 2007 开始,Microsoft 引入了新的文件格式------Office Open XML (OOXML),扩展名为.pptx。
OOXML 是基于 zip+xml 定义的压缩文件格式,内部包含了多个 XML 文件,每个文件定义了 PPT 的不同部分,如幻灯片、备注、主母版等。
与旧的二进制格式相比,OOXML 更容易被解析和修改,因为它本质上是由文本构成的,并且有公开的规范文档。
既然是 zip 格式,那么我们解压一个 pptx 看看。
由上可以看到,PPTX 文件里居然由文件夹及xml文件组成,其中的文件夹结构是遵循开放打包协议 OPC (Open Package Convention) 去组织的, 相关的规范可以参考 ECMA-376 Part 2,其中重点关注Part
、Relationship
和 Content Types
这三个核心概念,它们共同定义了文件包的结构和内容
Part
是OPC文件中的独立数据单元(如XML文件、图片),它们构成文件的主要内容,每个Part
有唯一标识符并存储于特定路径。举个例子
-
/ppt/slides/slide1.xml
: 包含第一个幻灯片的内容 -
/ppt/media/image1.png
: 一张用于幻灯片的图片
Relationship
定义了Part
之间的逻辑连接,即使文件结构改变,也能通过.rels
文件保持各部件间的有效链接。举个例子
-
/ppt/\_rels/presentation.xml.rels
: 定义了幻灯片与其他资源(如图片)之间的关系 -
/ppt/slides/\_rels/slide1.xml.rels
: 定义了第一张幻灯片内元素之间的关系,比如文本框和图片的位置
Content Types
则声明了每种Part
的数据格式,存储在[Content_Types].xml
中,帮助解析器正确处理文件内的资源。举个例子
<Default Extension="png" ContentType="image/png"/>
则定义了PNG图像的默认内容类型
3. 浅析 MarkUp Language
在上一小节了解到 pptx 的内容都是通过 xml 记录的,那怎么看懂呢?这时就需要用到 ECMA-376 Part 1规范了,里面定义了各位 *ML 的用途,见下表:
*ML | 全名 | 说明 |
---|---|---|
PML | Presentation Markup Language | PPT 中各种数据的描述 |
WML | Wordprocessing Markup Language | Word 中数据的描述 |
SML | Spreadsheet Markup Language | Excel 中数据的描述 |
DML | Drawing Markup Language | Office 所有格式中都可以使用,用来描述矢量图形,图表等 |
SharedML | Shared Markup Language | 描述了文档属性,音视频,图片,文档主题等内容,它被所有Office文件使用 |
其中 pptx 相关属性定义在 ECMA-376 Part 1 19.PresentationML Reference Material
(2527页),以 /ppt/presentation.xml
为例
可以检索文档查看 sldMasterIdLst
和 embeddedFontLst
对应的属性含义(其实大部分属性通过单词也可猜个大概)


4. 解析 PPTX 流程
经过上面的了解,解析 pptx 的基本流程大概可分为以下几步:
4.1. 解析 [Content_Types].xml 获取文件类型信息
读取位于文件包根目录下的[Content_Types].xml
文件,获取所有 Part 的内容类型声明,定义对应的类型文件处理逻辑。
4.2. 获取 Presentation 主文件位置
解析位于/_rels/.rels
的Package Relationship文件,从中找到指向presentation.xml
文件的关系条目。
presentation.xml
是整个演示文稿的主配置文件,通常位于/ppt/
目录下,它包含了关于幻灯片序列和其他全局设置的信息。
4.3. 解析 presentation.xml 及其关联关系
读取/ppt/presentation.xml
及其关联的Relationship文件/ppt/_rels/presentation.xml.rels
,以确定所有幻灯片(例如/ppt/slides/slide1.xml
)、母版(/ppt/slideMasters/slideMaster1.xml
)以及板式(/ppt/slideLayouts/
)的具体存储位置。
4.4. 解析幻灯片内容
对于每一个幻灯片文件(如/ppt/slides/slide1.xml
),读取其内容及对应的Relationship文件(如/ppt/slides/_rels/slide1.xml.rels
),以提取该幻灯片上的所有元素信息,包括文本、形状、图表、图像等。
这一过程可能涉及到深入理解PresentationML (PML)、DrawingML (DML) 和 SharedML中的细节,这些XML命名空间分别定义了幻灯片内容、绘图对象和共享元素的结构。
5. 浅析在线演示 PPTX
经过步骤4,我们可以得到 pptx 相关的内容数据,但要在 Web 端演示,还要将其转成前端相关的语言,然后渲染为 HTML 展示,所以需要定义一套 DSL(领域特定语言)。
这场景是不是似曾相识?没错,低代码平台也是类似实现思路。
我们可以将 .pptx 解析为 json 格式的数据,然后投喂给前端相关库渲染展示,比如 svg.js
、fabric
、konva
等,不考虑性能的话,甚至可以用 div
手搓。

6. 小结
PPT 分为 .ppt 和 .pptx 格式,其中.pptx 格式遵循 Office Open XML 规范,使得我们前端开发也可以按照文档规范解析 .pptx 内容,将内容数据转为特定的 DSL(领域特定语言),再配合前端库进行渲染展示,实现在线演示 ppt。
哦啦,本期分享到此,下期再分享一下实际的代码实现吧。