Office OpenXML -WordprocessingML 解析(一):样式
在 Office OpenXML(OOXML) WordprocessingML 文档中,样式是预定义的表格,编号,段落和字符属性的集合,能够应用于文档中的文本。下文主要了解样式的3个特性。
1. 同类样式之间的继承关系
样式可以继承于其他的同类型样式。这种继承关系是通过指定样式的basedOn
元素来实现的,元素的值表示其父样式的ID。
所以,为了获得某一样式的完整属性,应该遍历其继承树直到未指定basedOn
元素的样式。当同一属性在子样式和父样式中都出现时,子样式中的值会覆盖其父样式中的值。
例如,有如下两个样式:
// 标题 1
<w:style w:type="paragraph" w:styleId="1" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:name w:val="heading 1" />
<w:basedOn w:val="a" /> // 父样式StyleId为"a"
<w:qFormat />
<w:pPr>
<w:outlineLvl w:val="0" />
</w:pPr>
<w:rPr>
<w:rFonts w:eastAsia="黑体" />
</w:rPr>
</w:style>
// 正文
<w:style w:type="paragraph" w:styleId="a" w:default="1" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:name w:val="Normal" />
<w:qFormat />
<w:rsid w:val="002C5BB6" />
<w:pPr>
<w:jc w:val="center" />
</w:pPr>
<w:rPr>
<w:rFonts w:eastAsia="宋体" />
</w:rPr>
</w:style>
其中,“标题 1” 样式通过basedOn
元素指定其父样式为 “正文” 样式,那么,“标题 1” 样式继承了正文中的居中对齐属性,而它的中文字体 “黑体” 覆盖了正文中的 “宋体”。最终,“标题 1” 的样式为 黑体,居中,大纲级别1级。
2. 不同样式之间的应用顺序
样式有4种类型:表格、编号、段落和字符。不同类型的样式可以应用于文档中的同一内容,每种样式按下图的顺序来应用:
上图的流程如下:
- 首先,文档默认格式(document defaults)应用于文档中的所有 paragraph 和 run 元素;
- 然后,表格样式属性应用于文档中每一个引用此样式的表格;
- 接下来,编号样式属性应用于文档中的编号项;
- 然后,段落样式的 paragraph 和 run 属性应用于每一个引用此样式的段落;
- 再然后,字符样式的 run 属性应用于每一个引用该样式的 run;
- 最后,应用 paragraph 和 run 元素下的属性(direct formatting)。
3. Toggle(触发器)属性
在 WordprocessingML 文档中,Bold(加粗)是 toggle 属性。如前两节所述,多种样式可以同时影响文档同一块内容的格式。当同一属性出现在一个或多个应用于某个run的样式中时,共同作用的结果和它是否是 toggle 属性有关。
如果属性不是 toggle 属性,那么属性的值应该按照前两节的规则来确定,也就是流程中最后出现的值生效。
如果属性是 toggle 属性,它的值应该是 true
或 false
(或着 1 或 0),那么应该遵循以下规则:
- 如果一个 toggle 属性在内容的直接格式中有定义,那么应该使用直接格式中的值。
- 否则,toggle 属性的值按以下方式确定:
- 如果一个 toggle 属性出现在相同级别的不同样式中,那么应该采用按如下方式第一个出现的值(如果样式中均未出现该属性,那么该属性的值应该使用默认值):
- 尝试从样式中读取属性值;
- 如果样式中没有指定此属性但是指定了
basedOn
元素,那么使用baseOn
指定的父样式重复上述步骤。 - 例如:在一个段落样式中未指定
bold
属性,但是在其父样式中指定了该属性,并且值为true
。那么该样式的bold
属性为true
。
- 如果一个 toggle 属性出现在不同级别的多个样式中,那么它的值按照下述规则计算:
- 如果该属性在文档默认格式中的值为
true
,那么它的值就是true
。 - 反之,按照如下公式计算:
- value = val(table) XOR val(paragraph) XOR val(character)
- 如果该属性在文档默认格式中的值为
- 如果一个 toggle 属性出现在相同级别的不同样式中,那么应该采用按如下方式第一个出现的值(如果样式中均未出现该属性,那么该属性的值应该使用默认值):
例如,下面这样一个文档:
在表格中,表格应用了一个样式,指定第一行加粗;在第一个单元格中,文字“1行”指定了“标题 1” 字符样式,样式设置了加粗,如下所示:
表格样式:
<w:tblStylePr w:type="firstRow">
<w:rPr>
<w:b />
<w:bCs />
</w:rPr>
</w:tblStylePr>
"标题 1 字符" 样式:
<w:style w:type="character" w:styleId="10" w:customStyle="1" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:name w:val="标题 1 字符" />
<w:basedOn w:val="a0" />
<w:link w:val="1" />
<w:uiPriority w:val="9" />
<w:rsid w:val="00D8098D" />
<w:rPr>
<w:b />
<w:bCs />
<w:kern w:val="44" />
<w:sz w:val="44" />
<w:szCs w:val="44" />
</w:rPr>
</w:style>
根据上述规则,由于 bold 是 Toggle 属性,而且出现在了不同类型的样式中,所以首先判断 bold 属性在文档默认格式中的值是否为 true:
<w:docDefaults xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:rPrDefault>
<w:rPr>
<w:rFonts w:asciiTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:eastAsiaTheme="minorEastAsia" w:cstheme="minorBidi" />
<w:kern w:val="2" />
<w:sz w:val="21" />
<w:szCs w:val="21" />
<w:lang w:val="en-US" w:eastAsia="zh-CN" w:bidi="ar-SA" />
</w:rPr>
</w:rPrDefault>
<w:pPrDefault />
</w:docDefaults>
从上面可以看到,在默认值中没有指定 bold 元素,也就是说不符合第一个条件;
然后,按照公式 value = val(table) XOR val(paragraph) XOR val(character) 计算得出:
true XOR false XOR true => false
所以,最终的结果是 false, 也就是不加粗。
如果此时我们对第一个段落应用 “标题 2”段落样式,且“标题 2” 设置加粗,那么最终结果如下:
1 行 = true XOR true XOR true = true;
1 列 = true XOR true XOR false = false;
除了 Bold 外,下面这些元素也是 toggle 属性:bCs (Complex Script Bold) ,caps (Display All Characters As Capital Letters),emboss (Embossing),i (Italics),iCs (Complex Script Italics),iCs (Complex Script Italics),outline (Display Character Outline),shadow (Shadow),smallCaps (Small Caps),strike (Single Strikethrough),vanish (Hidden Text) 。
4. 参考
作者:扬帆,转载请注明原文链接:https://www.cnblogs.com/theyangfan/p/17071011.html
--- 💖 来自博客园 ---