创建字符样式并将其添加到字处理文档
本主题演示如何使用 Open XML SDK for Office 中的类以编程方式创建字符样式并将其添加到字处理文档。 它包含演示此任务的示例 CreateAndAddCharacterStyle
方法,以及在必要时添加样式部分的补充示例方法。
CreateAndAddCharacterStyle 方法
示例 CreateAndAddCharacterStyle
方法可用于向字处理文档添加样式。 您必须先获取对要将样式添加到的文档中的样式定义部分的引用。 有关演示如何执行此操作的示例,请参阅 调用示例方法 部分。
方法接受四个指示的参数:要编辑的文件的路径、样式 (内部标识符) 的样式 ID、用户界面) 中外部使用的样式 (的名称,以及(可选)在用户界面) 中使用的任何样式别名 (备用名称。
static void CreateAndAddCharacterStyle(string filePath, string styleid, string stylename, string aliases = "")
该方法的完整代码列表位于示例代码部分。
关于样式 ID、样式名称和别名
样式 ID 由文档用于引用样式,可被视为其主要标识符。 通常情况下,您可以使用样式 ID 标识代码中的样式。 样式还可具有在用户界面中显示的单独的显示名称。 因此,样式名称通常以正确的大小写和空格显示(例如 Heading 1),而样式 ID 则比较简洁(例如 heading1),旨在供内部使用。 别名指定可在应用程序的用户界面中使用的其他样式名称。
例如,考虑从样式定义中提取的以下 XML 代码示例。
<w:style w:type="character" w:styleId="OverdueAmountChar" . . .
<w:aliases w:val="Late Due, Late Amount" />
<w:name w:val="Overdue Amount Char" />
. . .
</w:style>
style 元素styleId
属性定义样式main内部标识符,样式 ID (OverdueAmountChar) 。 别名元素指定两个其他样式名称(Late Due 和 Late Amount),以逗号分隔。 每个名称必须由一个或多个逗号隔开。
最后,名称元素指定主要样式名称,即通常显示在应用程序的用户界面中的名称。
调用示例方法
可以使用 CreateAndAddCharacterStyle
示例方法使用 Open XML SDK 创建命名样式并将其添加到字处理文档。 下面的代码示例演示如何打开和获取对字处理文档的引用,检索对文档样式定义部分的引用,然后调用 CreateAndAddCharacterStyle
方法。
若要调用 方法,请将对文件的引用作为第一个参数进行编辑,将样式的样式 ID 作为第二个参数传递,将样式的名称作为第三个参数传递,还可以传递任何样式别名作为第四个参数。 例如,下面的代码示例在示例文件中创建“逾期金额字符”字符样式,其名称来自 方法的第一个参数。 它还会在段落中创建三段连续的文本,并将样式应用于第二段连续文本。
static void AddStylesToPackage(string filePath)
{
// Create and add the character style with the style id, style name, and
// aliases specified.
CreateAndAddCharacterStyle(
filePath,
"OverdueAmountChar",
"Overdue Amount Char",
"Late Due, Late Amount");
using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true))
{
// Add a paragraph with a run with some text.
Paragraph p = new Paragraph(
new Run(
new Text("this is some text ") { Space = SpaceProcessingModeValues.Preserve }));
// Add another run with some text.
p.AppendChild<Run>(new Run(new Text("in a run ") { Space = SpaceProcessingModeValues.Preserve }));
// Add another run with some text.
p.AppendChild<Run>(new Run(new Text("in a paragraph.") { Space = SpaceProcessingModeValues.Preserve }));
// Add the paragraph as a child element of the w:body.
doc?.MainDocumentPart?.Document?.Body?.AppendChild(p);
// Get a reference to the second run (indexed starting with 0).
Run r = p.Descendants<Run>().ElementAtOrDefault(1)!;
// If the Run has no RunProperties object, create one and get a reference to it.
RunProperties rPr = r.RunProperties ?? r.PrependChild(new RunProperties());
// Set the character style of the run.
if (rPr.RunStyle is null)
{
rPr.RunStyle = new RunStyle();
rPr.RunStyle.Val = "OverdueAmountChar";
}
}
}
样式类型
WordprocessingML 支持六种样式类型,其中四种可使用样式元素中的类型属性指定。 来自 ISO/IEC 29500 规范第 17.7.4.17 节的以下信息介绍了样式类型。
样式类型 指的是样式上的属性,用于定义使用此样式定义创建的样式的类型。 根据样式定义的类型属性的值,WordprocessingML 支持六种样式定义类型:
- 段落样式
- 字符样式
- 链接样式 (段落 + 字符) 通过链接元素完成 (§17.7.4.6) 。
- 表样式
- 编号样式
- 默认段落 + 字符属性
请考虑文档中名为“标题 1”的样式,如以下代码示例所示。
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="Normal"/>
<w:link w:val="Heading1Char"/>
<w:uiPriority w:val="1"/>
<w:qformat/>
<w:rsid w:val="00F303CE"/>
…
</w:style>
该类型属性的值为 paragraph,指示以下样式定义为段落样式。
可通过在样式元素的类型属性中指定相应的值来设置段落、字符、表和编号样式类型。
字符样式类型
可通过将样式元素上的类型属性的值设置为"character"来将字符指定为样式类型。
ISO/IEC 29500 规范的第 17.7.9 节中的以下信息讨论字符样式。 注意,§ 后面的章节编号指示 ISO 规范中的章节。
17.7.9 连续文本(字符)样式
字符样式 是应用于文档内容中一个或多个文本的内容的样式。 此定义暗示样式只能定义字符属性(应用于段落中的文本的属性),因为它无法应用于段落。
字符样式只能由文档中的运行引用,并且这些样式应由 run 的 run properties 元素中的 元素引用 rStyle
。
字符样式具有两个特定于定义样式类型的特征:
样式上的类型属性的值为字符,指示以下样式定义为字符样式。
样式仅使用
rPr
元素指定字符级属性。 在本例中,连续文本属性是应用于此样式的每段连续文本的属性集。
然后,通过在运行属性的 rStyle
元素中引用styleId
此样式的属性值,将字符样式应用于运行。
以下图像显示应用了字符样式的一些文本。 字符样式只能应用于分段落级别范围的文本。
图 1. 应用了字符样式的文本
代码的工作方式
方法 CreateAndAddCharacterStyle
首先打开指定的文件并检索对 styles 部件中 styles 元素的引用。 样式元素是该部分的根元素,包含所有单个样式元素。 如果引用为空,则会创建样式元素并将其保存到该部分。
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filePath, true))
{
// Get access to the root element of the styles part.
Styles? styles = wordprocessingDocument?.MainDocumentPart?.StyleDefinitionsPart?.Styles ?? AddStylesPartToPackage(wordprocessingDocument).Styles;
创建样式
为了创建样式,代码会实例化 Style 类并设置某些属性,例如 Type 样式 (段落) 、 StyleId、 以及样式是否为 CustomStyle。
// Create a new character style and specify some of the attributes.
Style style = new Style()
{
Type = StyleValues.Character,
StyleId = styleid,
CustomStyle = true
};
该代码生成以下 XML。
<w:style w:type="character" w:styleId="OverdueAmountChar" w:customStyle="true" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
</w:style>
接下来,该代码创建样式的子元素,这些元素用于定义样式的属性。 若要创建元素,请实例化其相应的类,然后调用 Append 方法将子元素添加到样式。 有关这些属性的详细信息,请参阅 ISO/IEC 29500 规范的第 17.7 部分。
// Create and add the child elements (properties of the style).
Aliases aliases1 = new Aliases() { Val = aliases };
StyleName styleName1 = new StyleName() { Val = stylename };
LinkedStyle linkedStyle1 = new LinkedStyle() { Val = "OverdueAmountPara" };
if (!String.IsNullOrEmpty(aliases))
{
style.Append(aliases1);
}
style.Append(styleName1);
style.Append(linkedStyle1);
接下来,代码实例化对象 StyleRunProperties 以创建 rPr
(运行属性) 元素。 您可在此元素中指定应用于样式的字符属性(如字体和颜色)。 然后,这些属性将追加为 元素的子级 rPr
。
创建运行属性时,代码会将 rPr
元素追加到样式,并将 style 元素追加到 styles 部件中的 styles 根元素。
// Create the StyleRunProperties object and specify some of the run properties.
StyleRunProperties styleRunProperties1 = new StyleRunProperties();
Bold bold1 = new Bold();
Color color1 = new Color() { ThemeColor = ThemeColorValues.Accent2 };
RunFonts font1 = new RunFonts() { Ascii = "Tahoma" };
Italic italic1 = new Italic();
// Specify a 24 point size.
FontSize fontSize1 = new FontSize() { Val = "48" };
styleRunProperties1.Append(font1);
styleRunProperties1.Append(fontSize1);
styleRunProperties1.Append(color1);
styleRunProperties1.Append(bold1);
styleRunProperties1.Append(italic1);
// Add the run properties to the style.
style.Append(styleRunProperties1);
// Add the style to the styles part.
styles.Append(style);
下面的 XML 显示此处显示的代码生成的最终样式。
<w:style w:type="character" w:styleId="OverdueAmountChar" w:customStyle="true" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:aliases w:val="Late Due, Late Amount" />
<w:name w:val="Overdue Amount Char" />
<w:link w:val="OverdueAmountPara" />
<w:rPr>
<w:rFonts w:ascii="Tahoma" />
<w:sz w:val="48" />
<w:color w:themeColor="accent2" />
<w:b />
<w:i />
</w:rPr>
</w:style>
应用字符样式
创建样式后,可以通过在运行属性的 元素中引用 styleId
此样式的 rStyle
属性值,将其应用于运行。 下面的代码示例演示如何将样式应用于变量 r 引用的连续文本。 要应用的样式的样式 ID,在此示例中,OverdueAmountChar 存储在 对象的 RunStyle 属性中 rPr
。 此属性表示运行属性的 rStyle
元素。
// If the Run has no RunProperties object, create one and get a reference to it.
RunProperties rPr = r.RunProperties ?? r.PrependChild(new RunProperties());
// Set the character style of the run.
if (rPr.RunStyle is null)
{
rPr.RunStyle = new RunStyle();
rPr.RunStyle.Val = "OverdueAmountChar";
}
示例代码
下面是 C# 和 Visual Basic 中的完整 CreateAndAddCharacterStyle
代码示例。
// Create a new character style with the specified style id, style name and aliases and
// add it to the specified file.
static void CreateAndAddCharacterStyle(string filePath, string styleid, string stylename, string aliases = "")
{
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filePath, true))
{
// Get access to the root element of the styles part.
Styles? styles = wordprocessingDocument?.MainDocumentPart?.StyleDefinitionsPart?.Styles ?? AddStylesPartToPackage(wordprocessingDocument).Styles;
if (styles is not null)
{
// Create a new character style and specify some of the attributes.
Style style = new Style()
{
Type = StyleValues.Character,
StyleId = styleid,
CustomStyle = true
};
// Create and add the child elements (properties of the style).
Aliases aliases1 = new Aliases() { Val = aliases };
StyleName styleName1 = new StyleName() { Val = stylename };
LinkedStyle linkedStyle1 = new LinkedStyle() { Val = "OverdueAmountPara" };
if (!String.IsNullOrEmpty(aliases))
{
style.Append(aliases1);
}
style.Append(styleName1);
style.Append(linkedStyle1);
// Create the StyleRunProperties object and specify some of the run properties.
StyleRunProperties styleRunProperties1 = new StyleRunProperties();
Bold bold1 = new Bold();
Color color1 = new Color() { ThemeColor = ThemeColorValues.Accent2 };
RunFonts font1 = new RunFonts() { Ascii = "Tahoma" };
Italic italic1 = new Italic();
// Specify a 24 point size.
FontSize fontSize1 = new FontSize() { Val = "48" };
styleRunProperties1.Append(font1);
styleRunProperties1.Append(fontSize1);
styleRunProperties1.Append(color1);
styleRunProperties1.Append(bold1);
styleRunProperties1.Append(italic1);
// Add the run properties to the style.
style.Append(styleRunProperties1);
// Add the style to the styles part.
styles.Append(style);
}
}
}
// Add a StylesDefinitionsPart to the document. Returns a reference to it.
static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument? doc)
{
StyleDefinitionsPart part;
if (doc?.MainDocumentPart is null)
{
throw new ArgumentNullException("MainDocumentPart is null.");
}
part = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
Styles root = new Styles();
return part;
}