Copiar conteúdos de uma peça de pacote Open XML para uma parte do documento num pacote diferente
Este tópico mostra como utilizar as classes no SDK Open XML para o Office para copiar o conteúdo de uma peça de documento Open XML Wordprocessing para uma parte do documento num documento de processamento de palavras diferente programaticamente.
Pacotes e partes do documento
Um documento Open XML é armazenado como um pacote, cujo formato é definido por ISO/IEC 29500. 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, instancia a WordprocessingDocument classe conforme mostrado nas duas using
instruções seguintes. Na mesma instrução, abre o ficheiro de processamento de palavras com o nome de ficheiro especificado através do Open método , com o parâmetro Booleano.
Para o ficheiro de origem que definiu o parâmetro para false
o abrir para acesso só de leitura. Para o ficheiro de destino, defina o parâmetro como para true
ativar a edição do documento.
using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
Com a v3.0.0+ o Close() método foi removido a favor de depender da instrução using.
Garante que o Dispose() método é chamado automaticamente quando a chaveta de fecho é atingida. O bloco que segue a instrução using estabelece um âmbito para o objeto que é criado ou nomeado na instrução using. Uma vez que a WordprocessingDocument classe no SDK Open XML guarda e fecha automaticamente o objeto como parte da respetiva IDisposable implementação e porque Dispose() é automaticamente chamada quando sai do bloco, não tem de chamar Save() explicitamente ou Dispose() desde que utilize uma using
instrução.
Estrutura de um Documento wordProcessingML
A estrutura de documentos básica de um WordProcessingML
documento consiste nos document
elementos e body
, 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 r
elementos. Significa r
execução, que é uma região de texto com um conjunto comum de propriedades, como formatação. Uma execução contém um ou mais t
elementos. O t
elemento contém um intervalo de texto. O seguinte exemplo de código mostra a WordprocessingML
marcação de um documento que contém o texto "Texto de exemplo".
<w:document xmlns:w="http://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>
Com o SDK Open XML, pode criar estrutura e conteúdo de documentos com classes com tipos fortes que correspondem a WordprocessingML
elementos. Encontrará estas classes no espaço de nomes. A tabela seguinte lista os nomes das classes que correspondem aos document
elementos , body
, p
, r
e t
.
WordprocessingML Element | Abrir Classe SDK XML | Descrição |
---|---|---|
<document/> |
Document | O elemento raiz para a parte do documento principal. |
<body/> |
Body | O contentor 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 do WordprocessingML, veja Structure of a WordprocessingML document (Estrutura de um documento wordprocessingML).
A Parte do Tema
A parte do tema contém informações sobre a cor, o tipo de letra e o formato de um documento. É definido na especificação ISO/IEC 29500 da seguinte forma.
Uma instância deste tipo de peça contém informações sobre o tema de um documento, que é uma combinação de esquema de cores, esquema de tipos de letra e esquema de formatação (este último também é referido como efeitos). Para um documento do WordprocessingML, a escolha do tema afeta a cor e o estilo dos cabeçalhos, entre outras coisas. Para um documento de Folha de CálculoML, a escolha do tema afeta a cor e o estilo dos conteúdos e gráficos das células, entre outras coisas. Para um documento PresentationML, a escolha do tema afeta a formatação de diapositivos, folhetos e notas através do master associado, entre outras coisas.
Um pacote WordprocessingML ou Folha de Cálculo deve conter zero ou uma parte do Tema, que será alvo de uma relação implícita numa parte do Documento Principal (\11.3.10) ou livro (\12.3.23). Um pacote PresentationML deve conter zero ou uma peça Tema por Modelo Global de Folhetos (}13.3.3), Modelo Global de Notas (}13.3.4), Modelo Global de Diapositivos (}13.3.10) ou Apresentação (}13.3.6) através de uma relação implícita.
Exemplo: o seguinte item de relação de partes 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/IEC 29500: 2016
Como funciona o código de exemplo
Para copiar o conteúdo de uma peça de documento num pacote Open XML para uma parte do documento num pacote diferente, o caminho completo de cada documento de processamento de palavras é transmitido como um parâmetro para o CopyThemeContent
método . Em seguida, o código abre ambos os documentos como WordprocessingDocument objetos e cria variáveis que referenciam as ThemePart partes em cada um dos pacotes.
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 peça de origem ThemePart com um StreamReader
objeto e escreve na parte de destino ThemePart com um 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 seguinte copia o conteúdo de uma parte do documento num pacote Open XML para uma parte do documento num pacote diferente. Para chamar o CopyThemeContent
método, pode utilizar o seguinte exemplo, que copia a parte do tema dos pacotes localizados em args[0]
para um localizado em args[1]
.
string fromDocument1 = args[0];
string toDocument2 = args[1];
CopyThemeContent(fromDocument1, toDocument2);
Importante
Antes de executar o programa, certifique-se de que o documento de origem tem a peça de tema definida. Para adicionar um tema a um documento, abra-o no Microsoft Word, clique no separador Estrutura e, em seguida, clique em Temas e selecione um dos temas disponíveis.
Depois de executar o programa, pode inspecionar o ficheiro para ver o tema alterado.
A seguir está o código de exemplo completo em C# e em Visual Basic.
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());
}
}
}