准备
- 扎实的Python基础,知道如何python标准库:zipfile的使用方法。
- 拥有xml基础,以及知道如何理解xsd(XML Schema)文件。
- 知道或了解ECMA-376标准。
- 熟悉svg矢量化图形语言(标记),并能使用svg绘制图形。(了解原理即可)
- HTML/CSS前端基础。
- 其他视频、音频、图片等方面的基本知识。
前言
OPEN XML 标准, 基于官方文档,就是是一个基于xml的词汇表,但这些词汇表代表了不同的意义。以此来表达不同的元素和意图。
初探
.pptx文件
将文件后缀的.pptx 改为 .zip, 则可以利用电脑自身的软件,将文件解压,看到pptx文件内部的组织结构,就不会那么像一个黑匣子一样了。
如下所示:
.xlsx文件
暂时忽略
.words文件
暂时忽略
OPC开放打包标准
OPC 是英文 Open Packaging Conventions 的缩写,直译过来就是 开放包约定, 也就是 open office 中,.pptx、.xlsx、.words 这三类文档基于zip压缩格式的文件内部,文件的组织安排方式。
其中,需要注意的是,基于opc的包,解压后,里面的文件不是普通意义上的文件,而是有一定特殊意义的,有特定作用的文件,并且在opc中将之称为部件(part)。
每个部件又有三个维度的基本属性,部件的文件名称、部件存放位置、部件内容类型。
这里要强调一下:
- 部件的文件名称: 这里之所以要用这么拗口的部件的文件名称,而不用部件名称,是因为部件根据内容类型的不同,其部件内部的还有可能有其他属性表示该部件的,具有特定意义的名称,或是作为关系的目标部件,或是作为媒体部件的关系部件时,容易与部件名称相混淆。
- 部件存放位置:为了保证打包后,文件的体积达到最小,所以基本上opc包中的部件基本上都具有唯一性,也就时同一个部件,不会存在多份,如果多个地方需要使用同一个部件(比如,同一个图片部件),则用关系的方式引用。
- 部件内容类型:在opc包中,虽然具有很多相同后缀的部件文件(比如,app.xml、core.xml),但他们每个部件文件的内容中代表的含义则各不相同。需要用不同的规则/方式去理解/解析里面的内容。
内容类型
在包的根目录,有一个部件为:[Content_types].xml,其中的内容大概如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="emf" ContentType="image/x-emf"/>
<Default Extension="jpeg" ContentType="image/jpeg"/>
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Default Extension="png" ContentType="image/png"/>
<Override PartName="/ppt/notesSlides/notesSlide1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"/>
<Override PartName="/ppt/notesSlides/notesSlide2.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"/>
<Override PartName="/ppt/notesSlides/notesSlide3.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"/>
<Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/>
<Override PartName="/ppt/slideLayouts/slideLayout4.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>
<Override PartName="/ppt/slideLayouts/slideLayout5.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>
<Override PartName="/ppt/slideLayouts/slideLayout6.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>
...
<Override PartName="/ppt/charts/chart1.xml" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
</Types>
该文件主要说明了,opc包中各个部件的内容的类型,比如,
<Default> 标签中
<Default Extension="jpeg" ContentType="image/jpeg"/>
在默认情况下,部件文件名称后缀为.jpeg的部件,则可以将其的内容视为image/jpeg格式的内容,也就是各类图片中的jpeg图片。
而<Override> 标签中
<Override PartName="/ppt/notesSlides/notesSlide1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"/>
则比Default标签中的说明更有说服力,因为这里直接指出了具体的部件位置,也就是部件/ppt/notesSlides/notesSlide1.xml 中的内容,则应视为application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml 格式的内容,也就是幻灯片中笔记幻灯片的内容,其中基于xml表示。
在后面的解析pptx具体某个部件时,要判断该部件的内容,则依据内容类型部件中说明,来决定该部件的内容类型,并调用相应函数/类/模块的代码,来解析该部件。
关系
因为pptx主要作为演示的解决方案,所以在制作幻灯片时,其中可能会涉及各种各样的元素,比如:图片,文字,视频,音频,等等。但这些元素又能根据需要设置/编辑不同的样式/颜色/边框。特别是图片时,一个图片可能会被多个幻灯片页面同时引用。
所以这里就需要一个载体表示一个部件被哪些其他部件所引用,因此这里引申出了一类特殊的部件。以.rels后缀结尾的部件文件。又称为关系部件。
每个特殊部件都会有一个关系部件,位于同级目录rels下,比如, 部件 /ppt/slides/slide1.xml 的关系部件位于/ppt/slides/rels/slide1.xml.rels
如图所示:
其内容大致如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image2.emf"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide" Target="../notesSlides/notesSlide3.xml"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout2.xml"/>
</Relationships>
</Relationships>
该关系部件内容表示,部件 /ppt/slides/slide1.xml 具有三个引用其他部件的关系,并且在关系中指定了目标部件,以及该部件的关系类型
最后
这里大致介绍了pptx文件的内部结构,以及对于我们开发来说,比较有意义的关系的表示,以及组织方式,具体的OPC标准,还请阅读官方文档中的第二部分:Part 2 “Open Packaging Conventions”, 5th edition, December 2021
如果有其他问题,欢迎评论,留言。