Compartilhar via


Copiar conteúdo de uma parte do pacote Open XML para uma parte do documento em um pacote diferente

Este tópico mostra como usar as classes no SDK Do Open XML para Office para copiar o conteúdo de uma parte do documento de Processamento de Palavras Open XML para uma parte do documento em um documento de processamento de palavras diferente programaticamente.


Pacotes e partes do documento

Um documento Open XML é armazenado como um pacote, cujo formato é definido pela ISO/IEC 29500-2. O pacote pode ter várias partes com relações entre elas. A relação entre as partes controla a categoria do documento. Um documento pode ser definido como um documento de processamento de texto caso seu item de relação do pacote contiver uma relação com uma parte do documento principal. Caso seu item de relação do pacote contenha uma relação com uma parte da apresentação, ela poderá ser definida como um documento de apresentação. Caso seu item de relação do pacote contenha uma relação com uma parte da pasta de trabalho, ela é definida como um documento de planilha. Neste tópico de tutorial, você usará um pacote de documentos de processamento de texto.


Como obter um objeto WordprocessingDocument

Para abrir um documento existente, instancie a classe WordprocessingDocument , conforme mostrado nas duas instruções a seguir. Na mesma instrução, você abre o arquivo de processamento de palavras com o nome do arquivo especificado usando o método Open , com o parâmetro booliano. Para o arquivo de origem que define o parâmetro como false para abri-lo para acesso somente leitura. Para o arquivo de destino, defina o parâmetro como true para habilitar a edição do documento.

    using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
    using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
    {
        // Insert other code here.
    }

A instrução de uso fornece uma alternativa recomendada ao típico . Criar. Salvar. Fechar sequência. Ela garante que o método Dispose (método interno usado pelo SDK do Open XML para limpar recursos) seja chamado automaticamente quando a chave de fechamento for atingida. O bloco que segue a instrução de uso estabelece um escopo para o objeto que é criado ou nomeado na instrução de uso . Como a classe WordprocessingDocument no SDK do Open XML salva automaticamente e fecha o objeto como parte de sua implementação do System.IDisposable e, como Dispose é chamado automaticamente quando você sai do bloco, não é necessário chamar explicitamente Save e Close - desde que using seja usado.


Estrutura de um documento WordProcessingML

A estrutura básica do documento de um documento WordProcessingML consiste nos elementos do documento e do corpo , seguidos por um ou mais elementos de nível de bloco, como p, que representa um parágrafo. Um parágrafo contém um ou mais elementos r . O r significa run, que é uma região de texto com um conjunto comum de propriedades, como a formatação. Uma execução contém um ou mais elementos t . O elemento t contém um intervalo de texto. O exemplo de código a seguir mostra a marcação WordprocessingML para um documento que contém o texto "Texto de exemplo".

    <w:document xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
      <w:body>
        <w:p>
          <w:r>
            <w:t>Example text.</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:document>

Usando o SDK do Open XML, você pode criar estrutura de documentos e conteúdo usando classes fortemente tipdas que correspondem aos elementos WordprocessingML . Você encontrará essas classes no namespace DocumentFormat.OpenXml.Wordprocessing . A tabela a seguir lista os nomes de classe das classes que correspondem aos elementos documento, corpo, p, r e t .

Elemento WordprocessingML Classe SDK Open XML Descrição
document Document O elemento raiz para a parte do documento principal.
corpo Body O contêiner para as estruturas de nível de bloco, como parágrafos, tabelas, anotações e outros especificados na especificação ISO/IEC 29500 .
p Paragraph Um parágrafo.
r Run Uma execução.
t Text Um intervalo de texto.

Para obter mais informações sobre a estrutura geral das partes e elementos de um documento WordprocessingML, consulte Estrutura de um documento WordprocessingML.


A Parte do Tema

A parte do tema contém informações sobre a cor, a fonte e o formato de um documento. Ele é definido na especificação ISO/IEC 29500 da seguinte maneira.

Uma instância desse tipo de parte contém informações sobre o tema de um documento, que é uma combinação de esquema de cores, esquema de fonte e esquema de formato (este último também está sendo chamado de efeitos). Para um documento WordprocessingML, a escolha do tema afeta a cor e o estilo dos títulos, entre outras coisas. Para um documento SpreadsheetML, a escolha do tema afeta a cor e o estilo de conteúdo e gráficos de células, entre outras coisas. Para um documento PresentationML, a escolha do tema afeta a formatação de slides, apostilas e anotações por meio do master associado, entre outras coisas.

Um pacote WordprocessingML ou SpreadsheetML deve conter zero ou uma parte tema, que deve ser o destino de uma relação implícita em uma parte Documento Principal (§11.3.10) ou Pasta de Trabalho (§12.3.23). Um pacote PresentationML deve conter zero ou uma parte do Tema por Mestre de Apostila (§13.3.3), Mestre de Notas (§13.3.4), Mestre de Slides (§13.3.10) ou Apresentação (§13.3.6) por meio de uma relação implícita.

Exemplo: o seguinte item de relação de parte do Documento Principal do WordprocessingML contém uma relação com a parte Tema, que é armazenada no tema do item ZIP/theme1.xml:

    <Relationships xmlns="…">
       <Relationship Id="rId4"
          Type="https://…/theme" Target="theme/theme1.xml"/>
    </Relationships>

© ISO/IEC29500: 2008.


Como funciona o código de exemplo

Para copiar o conteúdo de uma parte do documento em um pacote Open XML para uma parte do documento em um pacote diferente, o caminho completo de cada documento de processamento de palavras é passado como um parâmetro para o método CopyThemeContent . Em seguida, o código abre os dois documentos como objetos WordprocessingDocument e cria variáveis que fazem referência às partes ThemePart em cada um dos pacotes.

    public static void CopyThemeContent(string fromDocument1, string toDocument2)
    {
       using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
       using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
       {
          ThemePart themePart1 = wordDoc1.MainDocumentPart.ThemePart;
          ThemePart themePart2 = wordDoc2.MainDocumentPart.ThemePart;

Em seguida, o código lê o conteúdo da parte ThemePart de origem usando um objeto StreamReader e grava na parte ThemePart de destino usando um objeto StreamWriter .

    using (StreamReader streamReader = new StreamReader(themePart1.GetStream()))
    using (StreamWriter streamWriter = new StreamWriter(themePart2.GetStream(FileMode.Create))) 
    {
        streamWriter.Write( streamReader.ReadToEnd());
    }

Código de exemplo

O código a seguir copia o conteúdo de uma parte de documento em um pacote Open XML para uma parte do documento em um pacote diferente. Para chamar o método CopyThemeContent , você pode usar o exemplo a seguir, que copia a parte do tema de "MyPkg4.docx" para "MyPkg3.docx".

    string fromDocument1 = @"C:\Users\Public\Documents\MyPkg4.docx";
    string toDocument2 = @"C:\Users\Public\Documents\MyPkg3.docx";
    CopyThemeContent(fromDocument1, toDocument2);

Importante

Antes de executar o programa, verifique se o documento de origem (MyPkg4.docx) tem o conjunto de partes do tema; caso contrário, uma exceção seria gerada. Para adicionar um tema a um documento, abra-o em Microsoft Word 2013, clique na guia Layout da Página, clique em Temas e selecione um dos temas disponíveis.

Depois de executar o programa, você pode inspecionar o arquivo "MyPkg3.docx" para ver o tema copiado do arquivo "MyPkg4.docx".

A seguir está o código de exemplo completo em C# e em Visual Basic.


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

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

// To copy contents of one package part.
static void CopyThemeContent(string fromDocument1, string toDocument2)
{
    using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
    using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
    {
        ThemePart? themePart1 = wordDoc1?.MainDocumentPart?.ThemePart;
        ThemePart? themePart2 = wordDoc2?.MainDocumentPart?.ThemePart;

        // If the theme parts are null, then there is nothing to copy.
        if (themePart1 is null || themePart2 is null)
        {
            return;
        }

        using (StreamReader streamReader = new StreamReader(themePart1.GetStream()))
        using (StreamWriter streamWriter = new StreamWriter(themePart2.GetStream(FileMode.Create)))
        {
            streamWriter.Write(streamReader.ReadToEnd());
        }
    }
}

Confira também