从字处理文档中提取样式

本主题演示如何使用 Open XML SDK for Office 中的类以编程方式将样式或样式WithEffects 部分从字处理文档提取到 XDocument 实例。 它包含演示此任务的示例 ExtractStylesPart 方法。


ExtractStylesPart 方法

可以使用ExtractStylesPart示例方法检索一个XDocument实例,该实例包含Microsoft Word文档的 styles 或 stylesWithEffects 部件。 请注意,在 2010 Word 创建的文档中,只有一个样式部分;Word 2013+ 添加了第二个 stylesWithEffects 部分。 为了提供从 Word 2013+ 到 2010 Word 及之后的文档的“往返”,Word 2013+ 会同时保留原始样式部分和新样式部分。 (Office Open XML 文件格式规范要求Microsoft Word忽略它无法识别的任何部分:Word 2010 不会注意到Word 2013+ 添加到 document 的 stylesWithEffects 部分。) 你 (和应用程序) 必须解释检索样式或 stylesWithEffects 部分的结果。

该过程ExtractStylesPart接受两个参数:第一个参数包含一个字符串,指示要从中提取样式的文件的路径,第二个参数指示是要检索样式部分,还是较新的 stylesWithEffects 部分 (基本上,您必须为Word 2013+ 文档调用此过程两次,检索每个部分) 。 如果请求的) 部件不存在,则该过程返回一个 XDocument 实例,该实例包含所请求的完整样式或 stylesWithEffects 部分,其中包含文档的所有样式信息 (或 null 引用。

static XDocument? ExtractStylesPart(string fileName, string getStylesWithEffectsPart = "true")

该方法的完整代码列表位于示例代码部分。


调用示例方法

若要调用示例方法,请为第一个参数传递一个字符串,其中包含要从中提取样式的文档的文件名,并为第二个参数传递一个布尔值,该参数指定要检索的部件的类型是 styleWithEffects 部件 () true ,还是样式部分 (false) 。 下面的示例代码显示了一个示例。 拥有实例时, XDocument 可以使用它执行所需操作;在以下示例代码中,实例的内容 XDocument 将显示在控制台中。

if (args is [{ } fileName, { } getStyleWithEffectsPart])
{
    var styles = ExtractStylesPart(fileName, getStyleWithEffectsPart);

    if (styles is not null)
    {
        Console.WriteLine(styles.ToString());
    }
}
else if (args is [{ } fileName2])
{
    var styles = ExtractStylesPart(fileName2);

    if (styles is not null)
    {
        Console.WriteLine(styles.ToString());
    }
}

代码的工作方式

代码首先创建一个名为 的 styles 变量,以包含 方法的返回值。 代码继续使用 方法打开文档 Open ,并指示文档应打开以便进行只读访问, (最终的 false 参数) 。 给定打开的文档,代码使用 MainDocumentPart 属性导航到 main 文档部件,然后准备一个名为 的stylesPart变量来保存对样式部件的引用。

// Declare a variable to hold the XDocument.
XDocument? styles = null;

// Open the document for read access and get a reference.
using (var document = WordprocessingDocument.Open(fileName, false))
{
    if (
        document.MainDocumentPart is null ||
        (document.MainDocumentPart.StyleDefinitionsPart is null && document.MainDocumentPart.StylesWithEffectsPart is null)
    )
    {
        throw new ArgumentNullException("MainDocumentPart and/or one or both of the Styles parts is null.");
    }

    // Get a reference to the main document part.
    var docPart = document.MainDocumentPart;

    // Assign a reference to the appropriate part to the
    // stylesPart variable.
    StylesPart? stylesPart = null;

查找正确的 Styles 部分

接下来,代码使用 getStylesWithEffectsPartBoolean 参数检索对请求的样式部分的引用。 根据此值,代码会检索 docPart 变量的特定属性,并将其存储在 stylesPart 变量中。

if (getStylesWithEffectsPart.ToLower() == "true")
{
    stylesPart = docPart.StylesWithEffectsPart;
}
else
{
    stylesPart = docPart.StyleDefinitionsPart;
}

检索部分内容

如果请求的样式部件存在,则代码必须在实例中 XDocument 返回该部分的内容。 每个部分都提供一个GetStream()方法,该方法返回Stream。 代码将 Stream 实例传递给 Create 方法,然后调用 Load 方法,并将 XmlNodeReader 作为参数传递。

if (stylesPart is not null)
{
    using var reader = XmlNodeReader.Create(stylesPart.GetStream(FileMode.Open, FileAccess.Read));

    // Create the XDocument.
    styles = XDocument.Load(reader);
}

示例代码

下面是 C# 和 Visual Basic 中的完整 ExtractStylesPart 示例代码。

using DocumentFormat.OpenXml.Packaging;
using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;


// Extract the styles or stylesWithEffects part from a 
// word processing document as an XDocument instance.
static XDocument? ExtractStylesPart(string fileName, string getStylesWithEffectsPart = "true")
{
    // Declare a variable to hold the XDocument.
    XDocument? styles = null;

    // Open the document for read access and get a reference.
    using (var document = WordprocessingDocument.Open(fileName, false))
    {
        if (
            document.MainDocumentPart is null ||
            (document.MainDocumentPart.StyleDefinitionsPart is null && document.MainDocumentPart.StylesWithEffectsPart is null)
        )
        {
            throw new ArgumentNullException("MainDocumentPart and/or one or both of the Styles parts is null.");
        }

        // Get a reference to the main document part.
        var docPart = document.MainDocumentPart;

        // Assign a reference to the appropriate part to the
        // stylesPart variable.
        StylesPart? stylesPart = null;

        if (getStylesWithEffectsPart.ToLower() == "true")
        {
            stylesPart = docPart.StylesWithEffectsPart;
        }
        else
        {
            stylesPart = docPart.StyleDefinitionsPart;
        }

        if (stylesPart is not null)
        {
            using var reader = XmlNodeReader.Create(stylesPart.GetStream(FileMode.Open, FileAccess.Read));

            // Create the XDocument.
            styles = XDocument.Load(reader);
        }
    }
    // Return the XDocument instance.
    return styles;
}

另请参阅