Obter todo o texto de um slide de uma apresentação
Este tópico mostra como usar as classes no SDK do Open XML para Office para obter todo o texto em um slide em uma apresentação de forma programática.
Obtendo um objeto PresentationDocument
No SDK do Open XML, a classe PresentationDocument representa um pacote de documento de apresentação. Para trabalhar com um documento de apresentação, primeiro crie uma instância da classe PresentationDocument e trabalhe com essa instância. Para criar a instância de classe a partir do documento, chame o método PresentationDocument.Open(String, Boolean) que usa um caminho de arquivo e um valor booliano como o segundo parâmetro para especificar se um documento é editável. Para abrir um documento para acesso de leitura/gravação, atribua o valor true a esse parâmetro; para acesso somente leitura, atribua-lhe o valor false , conforme mostrado na instrução de uso a seguir. Neste código, o parâmetro de arquivo é uma cadeia de caracteres que representa o caminho para o arquivo do qual você deseja abrir o documento.
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Insert other code here.
}
A instrução using fornece uma alternativa recomendada para a sequência típica de .Open, .Save e .Close. 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 usando , nesse caso , presentationDocument.
Estrutura básica do documento de apresentação
A estrutura básica do documento de um documento PresentationML consiste em várias partes, entre elas a main parte que contém a definição de apresentação. O texto a seguir da especificação ISO/IEC 29500 apresenta a forma geral de um pacote PresentationML .
A main parte de um pacote PresentationML começa com um elemento raiz de apresentação. Esse elemento contém uma apresentação que, por sua vez, se refere a uma lista de slides, uma lista de master de slides, uma lista de master de anotações e uma lista de master de apostila. A lista de slides refere-se a todos os slides na apresentação; A lista de master de slides refere-se a todos os mestres de slides usados na apresentação; as anotações master contém informações sobre a formatação de páginas de anotações; e a apostila master descreve como uma apostila parece.
Uma apostila é um conjunto impresso de slides que pode ser fornecido a uma audiência.
Além de texto e gráficos, cada slide pode conter comentários e anotações, pode ter um layout e pode fazer parte de uma ou mais apresentações personalizadas. Um comentário é uma anotação destinada à pessoa que mantém o deck de slides de apresentação. Uma nota é um lembrete ou um pedaço de texto destinado ao apresentador ou ao público-alvo.
Outros recursos que um documento PresentationML pode incluir o seguinte: animação, áudio, vídeo e transições entre slides.
Um documento PresentationML não é armazenado como um corpo grande em uma única parte. Em vez disso, os elementos que implementam determinados agrupamentos de funcionalidade são armazenados em partes separadas. Por exemplo, todos os comentários em um documento são armazenados em uma parte de comentário, enquanto cada slide tem sua própria parte.
© ISO/IEC29500: 2008.
O exemplo de código XML a seguir representa uma apresentação que contém dois slides denotados pelas IDs 267 e 256.
<p:presentation xmlns:p="…" … >
<p:sldMasterIdLst>
<p:sldMasterId
xmlns:rel="https://…/relationships" rel:id="rId1"/>
</p:sldMasterIdLst>
<p:notesMasterIdLst>
<p:notesMasterId
xmlns:rel="https://…/relationships" rel:id="rId4"/>
</p:notesMasterIdLst>
<p:handoutMasterIdLst>
<p:handoutMasterId
xmlns:rel="https://…/relationships" rel:id="rId5"/>
</p:handoutMasterIdLst>
<p:sldIdLst>
<p:sldId id="267"
xmlns:rel="https://…/relationships" rel:id="rId2"/>
<p:sldId id="256"
xmlns:rel="https://…/relationships" rel:id="rId3"/>
</p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000"/>
<p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>
Usando o SDK do Open XML, você pode criar estrutura de documentos e conteúdo usando classes fortemente tipdas que correspondem a elementos PresentationML. Você pode encontrar essas classes no namespace DocumentFormat.OpenXml.Presentation . A tabela a seguir lista os nomes de classe das classes que correspondem aos elementos sld, sldLayout, sldMaster e notesMaster .
Elemento PresentationML | Classe SDK Open XML | Descrição |
---|---|---|
Sld | Slide | Slide de Apresentação. É o elemento raiz do SlidePart. |
sldLayout | SlideLayout | Layout do Slide. É o elemento raiz do SlideLayoutPart. |
sldMaster | SlideMaster | Mestre de Slides. É o elemento raiz do SlideMasterPart. |
notesMaster | NotesMaster | Mestre de Anotações (ou handoutMaster). É o elemento raiz do NotesMasterPart. |
Como funciona o código de exemplo
O código de exemplo consiste em três sobrecargas do método GetAllTextInSlide . No segmento a seguir, o primeiro método sobrecarregado abre a apresentação de origem que contém o slide com texto a ser obtido e passa a apresentação para o segundo método sobrecarregado, que obtém a parte do slide. Esse método retorna a matriz de cadeias de caracteres que o segundo método retorna a ele, cada uma das quais representa um parágrafo de texto no slide especificado.
// Get all the text in a slide.
public static string[] GetAllTextInSlide(string presentationFile, int slideIndex)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation and the slide index
// to the next GetAllTextInSlide method, and
// then return the array of strings it returns.
return GetAllTextInSlide(presentationDocument, slideIndex);
}
}
O segundo método sobrecarregado usa o documento de apresentação passado e obtém uma parte de slide para passar para o terceiro método sobrecarregado. Ele retorna ao primeiro método sobrecarregado a matriz de cadeias de caracteres que o terceiro método sobrecarregado retorna a ele, cada um dos quais representa um parágrafo de texto no slide especificado.
public static string[] GetAllTextInSlide(PresentationDocument presentationDocument, int slideIndex)
{
// Verify that the presentation document exists.
if (presentationDocument == null)
{
throw new ArgumentNullException("presentationDocument");
}
// Verify that the slide index is not out of range.
if (slideIndex < 0)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part of the presentation document.
PresentationPart presentationPart = presentationDocument.PresentationPart;
// Verify that the presentation part and presentation exist.
if (presentationPart != null && presentationPart.Presentation != null)
{
// Get the Presentation object from the presentation part.
Presentation presentation = presentationPart.Presentation;
// Verify that the slide ID list exists.
if (presentation.SlideIdList != null)
{
// Get the collection of slide IDs from the slide ID list.
var slideIds = presentation.SlideIdList.ChildElements;
// If the slide ID is in range...
if (slideIndex < slideIds.Count)
{
// Get the relationship ID of the slide.
string slidePartRelationshipId = (slideIds[slideIndex] as SlideId).RelationshipId;
// Get the specified slide part from the relationship ID.
SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);
// Pass the slide part to the next method, and
// then return the array of strings that method
// returns to the previous method.
return GetAllTextInSlide(slidePart);
}
}
}
// Else, return null.
return null;
}
O segmento de código a seguir mostra o terceiro método sobrecarregado, que usa a parte do slide passada e retorna ao segundo método sobrecarregado uma matriz de cadeia de caracteres de parágrafos de texto. Ele começa verificando se a parte do slide passada existe e, em seguida, cria uma lista vinculada de cadeias de caracteres. Ele itera pelos parágrafos no slide passado e usando um objeto StringBuilder para concatenar todas as linhas de texto em um parágrafo, ele atribui cada parágrafo a uma cadeia de caracteres na lista vinculada. Em seguida, ele retorna ao segundo método sobrecarregado uma matriz de cadeias de caracteres que representa todo o texto no slide especificado na apresentação.
public static string[] GetAllTextInSlide(SlidePart slidePart)
{
// Verify that the slide part exists.
if (slidePart == null)
{
throw new ArgumentNullException("slidePart");
}
// Create a new linked list of strings.
LinkedList<string> texts = new LinkedList<string>();
// If the slide exists...
if (slidePart.Slide != null)
{
// Iterate through all the paragraphs in the slide.
foreach (var paragraph in slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
{
// Create a new string builder.
StringBuilder paragraphText = new StringBuilder();
// Iterate through the lines of the paragraph.
foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
{
// Append each line to the previous lines.
paragraphText.Append(text.Text);
}
if (paragraphText.Length > 0)
{
// Add each paragraph to the linked list.
texts.AddLast(paragraphText.ToString());
}
}
}
if (texts.Count > 0)
{
// Return an array of strings.
return texts.ToArray();
}
else
{
return null;
}
}
Código de exemplo
A seguir está o código de exemplo completo que você pode usar para obter todo o texto em um slide específico em um arquivo de apresentação. Por exemplo, você pode usar o seguinte loop foreach em seu programa para obter a matriz de cadeias de caracteres retornada pelo método GetAllTextInSlide, que representa o texto no segundo slide do arquivo de apresentação "Myppt8.pptx".
foreach (string s in GetAllTextInSlide(@"C:\Users\Public\Documents\Myppt8.pptx", 1))
Console.WriteLine(s);
A seguir está o código de exemplo completo em C# e em Visual Basic.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
GetAllTextInSlide(args[0], int.Parse(args[1]));
// Get all the text in a slide.
static string[]? GetAllTextInSlide(string presentationFile, int slideIndex)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation and the slide index
// to the next GetAllTextInSlide method, and
// then return the array of strings it returns.
return GetAllTextInSlideFromPresentation(presentationDocument, slideIndex);
}
}
static string[]? GetAllTextInSlideFromPresentation(PresentationDocument presentationDocument, int slideIndex)
{
// Verify that the slide index is not out of range.
if (slideIndex < 0)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part of the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Verify that the presentation part and presentation exist.
if (presentationPart is not null && presentationPart.Presentation is not null)
{
// Get the Presentation object from the presentation part.
Presentation presentation = presentationPart.Presentation;
// Verify that the slide ID list exists.
if (presentation.SlideIdList is not null)
{
// Get the collection of slide IDs from the slide ID list.
DocumentFormat.OpenXml.OpenXmlElementList slideIds = presentation.SlideIdList.ChildElements;
// If the slide ID is in range...
if (slideIndex < slideIds.Count)
{
// Get the relationship ID of the slide.
string? slidePartRelationshipId = ((SlideId)slideIds[slideIndex]).RelationshipId;
if (slidePartRelationshipId is null)
{
return null;
}
// Get the specified slide part from the relationship ID.
SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);
// Pass the slide part to the next method, and
// then return the array of strings that method
// returns to the previous method.
return GetAllTextInSlideFromPart(slidePart);
}
}
}
// Else, return null.
return null;
}
static string[] GetAllTextInSlideFromPart(SlidePart slidePart)
{
// Verify that the slide part exists.
if (slidePart is null)
{
throw new ArgumentNullException("slidePart");
}
// Create a new linked list of strings.
LinkedList<string> texts = new LinkedList<string>();
// If the slide exists...
if (slidePart.Slide is not null)
{
// Iterate through all the paragraphs in the slide.
foreach (DocumentFormat.OpenXml.Drawing.Paragraph paragraph in
slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
{
// Create a new string builder.
StringBuilder paragraphText = new StringBuilder();
// Iterate through the lines of the paragraph.
foreach (DocumentFormat.OpenXml.Drawing.Text text in
paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
{
// Append each line to the previous lines.
paragraphText.Append(text.Text);
}
if (paragraphText.Length > 0)
{
// Add each paragraph to the linked list.
texts.AddLast(paragraphText.ToString());
}
}
}
// Return an array of strings.
return texts.ToArray();
}