Compartilhar via


Substituir as partes de estilos em um documento de processamento de texto

Este tópico mostra como usar as classes no SDK Open XML para Office para substituir programaticamente os estilos em um documento de processamento de palavras pelos estilos de outro documento de processamento de palavras. Ele contém um método ReplaceStyles de exemplo para ilustrar essa tarefa, bem como os métodos de suporte ReplaceStylesPart e ExtractStylesPart .


Sobre o Armazenamento de Estilos

Um pacote de documento de processamento de palavras, como um arquivo que tem uma extensão .docx, é de fato um arquivo .zip que consiste em várias partes. Você pode pensar em cada parte como sendo semelhante a um arquivo externo. Uma parte tem um tipo de conteúdo específico e pode conter conteúdo igual ao conteúdo de um arquivo XML externo, arquivo binário, arquivo de imagem e assim por diante, dependendo do tipo. O padrão que define como documentos Open XML são armazenados em arquivos .zip é chamado de Convenções de Embalagem Aberta. Para obter mais informações sobre as Convenções de Embalagem Aberta, consulte ISO/IEC 29500-2.

Os estilos são armazenados em partes dedicadas dentro de um pacote de documentos de processamento de palavras. Um documento Microsoft Word 2010 contém uma única parte de estilos. Microsoft Word 2013 adiciona uma segunda parte stylesWithEffects. A imagem a seguir do Documento Explorer na Ferramenta de Produtividade do SDK Open XML para Microsoft Office mostra as partes do documento em um exemplo Word documento de 2013 que contém estilos.

Figura 1. Partes de estilos em um documento de processamento de palavras

Partes de estilos em um documento de processamento de palavras. Para fornecer para "tropeços redondos" um documento de Word 2013 a Word 2010 e voltar, Word 2013 mantém a parte de estilos originais e a parte de novos estilos. (A especificação formatos de arquivo XML do Office Open exige que a Microsoft Word ignorar todas as partes que não reconhece; Word 2010 não percebe a parte stylesWithEffects que Word 2013 adiciona ao documento.)

O exemplo de código fornecido neste tópico pode ser usado para substituir essas partes de estilos.


Método ReplaceStyles

Você pode usar o método de exemplo ReplaceStyles para substituir os estilos em um documento de processamento de palavras pelos estilos em outro documento de processamento de palavras. O método ReplaceStyles aceita dois parâmetros: o primeiro parâmetro contém uma cadeia de caracteres que indica o caminho do arquivo que contém os estilos a serem extraídos. O segundo parâmetro contém uma cadeia de caracteres que indica o caminho do arquivo para o qual copiar os estilos, substituindo efetivamente completamente os estilos.

    public static void ReplaceStyles(string fromDoc, string toDoc)

A listagem de código completa para o método ReplaceStyles e seus métodos de suporte pode ser encontrada na seção Código de Exemplo .


Chamando o método de exemplo

Para chamar o método de exemplo, você passa uma cadeia de caracteres para o primeiro parâmetro que indica o caminho do arquivo com os estilos a serem extraídos e uma cadeia de caracteres para o segundo parâmetro que representa o caminho para o arquivo no qual substituir os estilos. O código de exemplo a seguir mostra um exemplo. Quando o código terminar de executar, os estilos no documento de destino serão substituídos e, consequentemente, a aparência do texto no documento refletirá os novos estilos.

    const string fromDoc = @"C:\Users\Public\Documents\StylesFrom.docx";
    const string toDoc = @"C:\Users\Public\Documents\StylesTo.docx";
    ReplaceStyles(fromDoc, toDoc);

Como o código funciona

O código extrai e substitui primeiro a parte de estilos e, em seguida, os estilosWithEffects parte segundo, e depende de dois métodos de suporte para fazer a maior parte do trabalho. O método ExtractStylesPart tem o trabalho de extrair o conteúdo da parte estilos ou estilosWithEffects e colocá-lo em um objeto XDocument . O método ReplaceStylesPart usa o objeto criado pelo ExtractStylesPart e usa seu conteúdo para substituir os estilos ou estilosWithEffects parte no documento de destino.

    // Extract and replace the styles part.
    var node = ExtractStylesPart(fromDoc, false);
    if (node != null)
        ReplaceStylesPart(toDoc, node, false);

O parâmetro final na assinatura para o método ExtractStylesPart ou ReplaceStylesPart determina se a parte de estilos ou a parte stylesWithEffects está empregada. Um valor de false indica que você deseja extrair e substituir a parte de estilos. A ausência de um valor (o parâmetro é opcional) ou um valor de true (o padrão), significa que você deseja extrair e substituir a parte stylesWithEffects.

    // Extract and replace the stylesWithEffects part. To fully support 
    // round-tripping from Word 2013 to Word 2010, you should 
    // replace this part, as well.
    node = ExtractStylesPart(fromDoc);
    if (node != null)
        ReplaceStylesPart(toDoc, node);
    return;

Para obter mais informações sobre o método ExtractStylesPart , consulte o exemplo associado. A seção a seguir explica o método ReplaceStylesPart .


Método ReplaceStylesPart

O método ReplaceStylesPart pode ser usado para substituir a parte estilosWithEffects em um documento, dada uma instância XDocument que contém a mesma parte para um documento Word 2010 ou Word 2013 (conforme mostrado no código de exemplo anteriormente neste tópico, o método ExtractStylesPart pode ser usado para obter essa instância). O método ReplaceStylesPart aceita três parâmetros: o primeiro parâmetro contém uma cadeia de caracteres que indica o caminho para o arquivo que você deseja modificar. O segundo parâmetro contém um objeto XDocument que contém os estilos ou estilosA parteWithEffect de outro documento de processamento de palavras, e o terceiro indica se você deseja substituir a parte de estilos ou a parte stylesWithEffects (conforme mostrado no código de exemplo anteriormente neste tópico, você precisará chamar esse procedimento duas vezes para Word documentos de 2013, substituindo cada parte pela parte correspondente de um documento de origem).

    public static void ReplaceStylesPart(string fileName, XDocument newStyles,
      bool setStylesWithEffectsPart = true)

Como funciona o código ReplaceStylesPart

O método ReplaceStylesPart examina o documento que você especifica, procurando a parte estilos ou estilosWithEffects. Se a parte solicitada existir, o método salvará o XDocument fornecido na parte selecionada.

O código começa abrindo o documento usando o método Open e indicando que o documento deve estar aberto para acesso de leitura/gravação (o parâmetro verdadeiro final). Dado o documento aberto, o código usa a propriedade MainDocumentPart para navegar até a parte do documento main e, em seguida, prepara uma variável chamada stylesPart para manter uma referência à parte de estilos.

    // Open the document for write access and get a reference.
    using (var document = 
        WordprocessingDocument.Open(fileName, true))
    {
        // 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;

Localizar a Parte de Estilos Corretos

O código em seguida recupera uma referência à parte estilos solicitados, usando o parâmetro setStylesWithEffectsPart Boolean. Com base nesse valor, o código recupera uma referência à parte estilos solicitados e o armazena na variável stylesPart .

    if (setStylesWithEffectsPart)
        stylesPart = docPart.StylesWithEffectsPart;
    else
        stylesPart = docPart.StyleDefinitionsPart;

Salvar o Conteúdo da Parte

Supondo que a parte solicitada exista, o código deve salvar todo o conteúdo do XDocument passado para o método para a parte. Cada parte fornece um método GetStream , que retorna um Stream. O código passa a instância stream para o construtor da classe StreamWriter , criando um gravador de fluxo ao redor do fluxo da parte. Por fim, o código chama o método Save do XDocument, salvando seu conteúdo na parte de estilos.

    // If the part exists, populate it with the new styles.
    if (stylesPart != null)
    {
        newStyles.Save(new StreamWriter(stylesPart.GetStream(
          FileMode.Create, FileAccess.Write)));
    }

Código de exemplo

A seguir estão os métodos ReplaceStyles, ReplaceStylesPart e ExtractStylesPart completos em C# e Visual Basic.

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

ReplaceStyles(args[0], args[1]);

// Replace the styles in the "to" document with the styles in
// the "from" document.
static void ReplaceStyles(string fromDoc, string toDoc)
{
    // Extract and replace the styles part.
    var node = ExtractStylesPart(fromDoc, false);
    if (node is not null)
        ReplaceStylesPart(toDoc, node, false);

    // Extract and replace the stylesWithEffects part. To fully support 
    // round-tripping from Word 2010 to Word 2007, you should 
    // replace this part, as well.
    node = ExtractStylesPart(fromDoc);
    if (node is not null)
        ReplaceStylesPart(toDoc, node);
    return;
}

// Given a file and an XDocument instance that contains the content of 
// a styles or stylesWithEffects part, replace the styles in the file 
// with the styles in the XDocument.
static void ReplaceStylesPart(string fileName, XDocument newStyles, bool setStylesWithEffectsPart = true)
{
    // Open the document for write access and get a reference.
    using (var document = WordprocessingDocument.Open(fileName, true))
    {
        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 (setStylesWithEffectsPart)
            stylesPart = docPart.StylesWithEffectsPart;
        else
            stylesPart = docPart.StyleDefinitionsPart;

        // If the part exists, populate it with the new styles.
        if (stylesPart is not null)
        {
            newStyles.Save(new StreamWriter(stylesPart.GetStream(
              FileMode.Create, FileAccess.Write)));
        }
    }
}

// Extract the styles or stylesWithEffects part from a 
// word processing document as an XDocument instance.
static XDocument ExtractStylesPart(string fileName, bool 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))
    {
        // Get a reference to the main document part.
        var docPart = document.MainDocumentPart;

        if (docPart is null || docPart.StyleDefinitionsPart is null || docPart.StylesWithEffectsPart is null)
        {
            throw new ArgumentNullException("MainDocumentPart and/or one or both of the Styles parts is null.");
        }

        // Assign a reference to the appropriate part to the
        // stylesPart variable.
        StylesPart? stylesPart = null;
        if (getStylesWithEffectsPart)
            stylesPart = docPart.StylesWithEffectsPart;
        else
            stylesPart = docPart.StyleDefinitionsPart;

        using (var reader = XmlNodeReader.Create(
          stylesPart.GetStream(FileMode.Open, FileAccess.Read)))
        {
            // Create the XDocument.
            styles = XDocument.Load(reader);
        }
    }
    // Return the XDocument instance.
    return styles;
}

Confira também