Compartilhar via


Abrir documento de uma apresentação para acesso somente leitura

Este tópico descreve como usar as classes no SDK do Open XML para Office para abrir programaticamente um documento de apresentação para acesso somente leitura.

Como abrir um arquivo para acesso Read-Only

Talvez você queira abrir um documento de apresentação para ler os slides. Talvez você queira extrair informações de um slide, copiar um slide para uma biblioteca de slides ou listar os títulos dos slides. Nesses casos, você deseja fazê-lo de uma maneira que garanta que o documento permaneça inalterado. Você pode fazer isso abrindo o documento para acesso somente leitura. Este How-To tópico discute várias maneiras de abrir programaticamente um documento de apresentação somente leitura.

Criar uma instância da classe 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 um dos métodos Open . Vários métodos Open são fornecidos, cada um com uma assinatura diferente. A tabela a seguir contém um subconjunto das sobrecargas para o método Open que você pode usar para abrir o pacote.

Nome Descrição
Open(String, booleano) Crie uma nova instância da classe PresentationDocument do arquivo especificado.
Open(Stream, Boolean) Crie uma nova instância da classe PresentationDocument a partir do fluxo de E/S.
Open(Package) Crie uma nova instância da classe PresentationDocument a partir do pacote especificado.

A tabela anterior inclui dois métodos Open que aceitam um valor booliano como o segundo parâmetro para especificar se um documento é editável. Para abrir um documento para acesso somente leitura, especifique o valor false para este parâmetro.

Por exemplo, você pode abrir o arquivo de apresentação como somente leitura e atribuí-lo a um objeto PresentationDocument , conforme mostrado na instrução a seguir. Neste código, o parâmetro presentationFile é uma cadeia de caracteres que representa o caminho do arquivo do qual você deseja abrir o documento.

    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Insert other code here.
    }

Você também pode usar a segunda sobrecarga do método Open , na tabela acima, para criar uma instância da classe PresentationDocument com base em um fluxo de E/S. Você pode usar essa abordagem se tiver um aplicativo Microsoft SharePoint Foundation 2010 que usa E/S de fluxo e quiser usar o SDK Open XML para trabalhar com um documento. O segmento de código a seguir abre um documento com base em um fluxo.

    Stream stream = File.Open(strDoc, FileMode.Open);
    using (PresentationDocument presentationDocument =
        PresentationDocument.Open(stream, false)) 
    {
        // Place other code here.
    }

Suponha que você tenha um aplicativo que emprega o suporte a Open XML no namespace System.IO.Packaging da Biblioteca de Classes .NET Framework e que deseja usar o SDK Open XML para trabalhar com um pacote somente leitura. O SDK do Open XML inclui uma sobrecarga de método que aceita um Pacote como o único parâmetro. Não há nenhum parâmetro booliano para indicar se o documento deve ser aberto para edição. A abordagem recomendada é abrir o pacote como somente leitura antes de criar a instância da classe PresentationDocument . O segmento de código a seguir executa essa operação.

    Package presentationPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read);
    using (PresentationDocument presentationDocument =
        PresentationDocument.Open(presentationPackage))
    {
        // Other code goes here.
    }

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

No código de exemplo, depois de abrir o documento de apresentação na instrução usando para acesso somente leitura, instancie a PresentationPart e abra a lista de slides. Em seguida, você obtém a ID de relacionamento do primeiro slide.

    // Get the relationship ID of the first slide.
    PresentationPart part = ppt.PresentationPart;
    OpenXmlElementList slideIds = part.Presentation.SlideIdList.ChildElements;
    string relId = (slideIds[index] as SlideId).RelationshipId;

Na ID do relacionamento, relId, você obtém a parte de slide e, em seguida, o texto interno do slide criando uma cadeia de caracteres de texto usando StringBuilder.

    // Get the slide part from the relationship ID.
    SlidePart slide = (SlidePart)part.GetPartById(relId);

    // Build a StringBuilder object.
    StringBuilder paragraphText = new StringBuilder();

    // Get the inner text of the slide.
    IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
    foreach (A.Text text in texts)
    {
        paragraphText.Append(text.Text);
    }
    sldText = paragraphText.ToString();

O texto interno do slide, que é um parâmetro fora do método GetSlideIdAndText, é passado de volta para o método main a ser exibido.

Importante

Este exemplo exibe apenas o texto no arquivo de apresentação. Partes não textuais, como formas ou gráficos, não são exibidas.

Código de exemplo

O exemplo a seguir abre um arquivo de apresentação para acesso somente leitura e obtém o texto interno de um slide em um índice especificado. Para chamar o método GetSlideIdAndText , passe o caminho completo do documento de apresentação. Também passe o parâmetro de saídasldText, que será atribuído um valor no próprio método e, em seguida, você pode exibir seu valor no programa main. Por exemplo, a chamada a seguir para o método GetSlideIdAndText obtém o texto interno no segundo slide em um arquivo de apresentação chamado "Myppt13.pptx".

Dica

A exceção mais esperada neste programa é a exceção ArgumentOutOfRangeException . Ele pode ser lançado se, por exemplo, você tiver um arquivo com dois slides e quiser exibir o texto no slide número 4. Portanto, é melhor usar um bloco de tentativa quando você chama o método GetSlideIdAndText , conforme mostrado no exemplo a seguir.

    string file = @"C:\Users\Public\Documents\Myppt13.pptx";
    string slideText;
    int index = 1;
    try
    {
        GetSlideIdAndText(out slideText, file, index);
        Console.WriteLine("The text in the slide #{0} is: {1}", index + 1, slideText);
    }
    catch (ArgumentOutOfRangeException exp)
    {
        Console.WriteLine(exp.Message);
    }

A seguir está a listagem completa de código em C# e Visual Basic.


using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using A = DocumentFormat.OpenXml.Drawing;

GetSlideIdAndText(out string text, args[0], int.Parse(args[1]));

static void GetSlideIdAndText(out string sldText, string docName, int index)
{
    using (PresentationDocument ppt = PresentationDocument.Open(docName, false))
    {
        // Get the relationship ID of the first slide.
        PresentationPart? part = ppt.PresentationPart;
        OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;

        // If there are no slide IDs then there are no slides.
        if (slideIds.Count == 0)
        {
            sldText = "";
            return;
        }

        string? relId = (slideIds[index] as SlideId)?.RelationshipId;

        if (relId is null)
        {
            sldText = "";
            return;
        }

        // Get the slide part from the relationship ID.
        SlidePart slide = (SlidePart)part!.GetPartById(relId);

        // Build a StringBuilder object.
        StringBuilder paragraphText = new StringBuilder();

        // Get the inner text of the slide:
        IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
        foreach (A.Text text in texts)
        {
            paragraphText.Append(text.Text);
        }
        sldText = paragraphText.ToString();
    }
}