从零写个Office(二):Office Open XML概述
ECMA-376指定了一系列的XML模式( XML schemas ),这些模式定义了诸如文字处理程序、电子表格、演示文档以及文档包所用的词汇表,也就是Office Open XML。
一、内容概述
在ECMA-376标准中主要包含下面几类
1. 标准W3C XML模式
XSD在ECMA-376-Fifteh-Edition-Part-1
[1]
中的
OfficeOpenXML-XMLSchema-Strict.zip
和
OfficeOpenXML-RELAXNG-Strict.zip
中。
2. XML语意描述
也就是文字处理(WordprocessingML)、电子表格(SpreadsheetML)、演示文档(PresentationML)、图像(DrawingML)。
3. 附加约束
(暂未使用)
二、包
Office Open XML文档是由一系列相互关联的部分组成的一个包(Package),这个包(Package)是一个普通的ZIP文件,其中包含了包的类型描述(
[Content_Types.xml]
)、关联关系(
.rels
、
document.xml.rels
)以及嵌套在文档中的内容、样式、信息、图片、视频、字体...之类的小块(Parts)
三、WordprocessingML
1. 段落
Word文档一般会有一块内容区,内容区中包含了段落、图片、表格等,每个段落由文本组成,这些文本、段落、图片、表格等我们可以通过工具栏进行样式的设置,比如粗体的文字、黄色边框的图片,而这些都是通过WordprocessingML来定义的。
如果有网页开发经验就很容易一下子联想到网页和HTML以及CSS的关系,事实上WordprocessingML与HTML确实如出一辙,只是标签存在较大的差异。
把上一节中
document.xml
拿出来看一下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex wp14">
<w:body>
<w:p w14:paraId="396385E8" w14:textId="6BF766E2" w:rsidR="00947F74" w:rsidRDefault="006640DB">
<w:rPr>
<w:rFonts w:hint="eastAsia" />
</w:rPr>
<w:t>这是一段文本</w:t>
<w:t xml:space="preserve"></w:t>
<w:sectPr w:rsidR="00947F74">
<w:pgSz w:w="11906" w:h="16838" />
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0" />
<w:cols w:space="425" />
<w:docGrid w:type="lines" w:linePitch="312" />
</w:sectPr>
</w:body>
</w:document>
WordproessingML包的文档处理部分用
w:document
包裹,其中
w:body
指定「身体」区域,
w:p
是一个段落,
w:r
是段落中的文本块,
w:t
则指定了文本内容,而
w:rPr
更像是一块样式。
将这段代码简化后,与 HTML进行对比:
2. 章节
WoreprocessingML文档通过章节(section)来组织,同样有点类似HTML中的
div
,不过由于WordprocessingML在文档的每页使用section布局,这也使得section可以有自己的页眉页脚。
3. 样式
像HTML的CSS样式表一样,WordprocessingML也会通过一些属性来改变内容的样式,之后通过「关系表」(relationship)与内容的各部分关联起来,有点像HTML外联样式表的做法。
通过观察上节中
styles.xml
文件可以发现一些端倪,下面是
styles.xml
的一段代码片段,还是能看到一些CSS的影子。如果做过Android开发,这种XML定义样式的方式则更是烂若披掌:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex">
<!--//.......-->
<w:style w:type="paragraph" w:default="1" w:styleId="a">
<w:name w:val="Normal" />
<w:qFormat />
<w:pPr>
<w:widowControl w:val="0" />
<w:jc w:val="both" />
</w:pPr>
</w:style>
<w:style w:type="character" w:default="1" w:styleId="a0">
<w:name w:val="Default Paragraph Font" />
<w:uiPriority w:val="1" />
<w:semiHidden />
<w:unhideWhenUsed />
</w:style>
<w:style w:type="table" w:default="1" w:styleId="a1">
<w:name w:val="Normal Table" />
<w:uiPriority w:val="99" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:tblPr>
<w:tblInd w:w="0" w:type="dxa" />
<w:tblCellMar>
<w:top w:w="0" w:type="dxa" />
<w:left w:w="108" w:type="dxa" />
<w:bottom w:w="0" w:type="dxa" />
<w:right w:w="108" w:type="dxa" />
</w:tblCellMar>
</w:tblPr>
</w:style>
<w:style w:type="numbering" w:default="1" w:styleId="a2">
<w:name w:val="No List" />