Compartilhar via


Inserir um novo slide em uma apresentação

Este tópico mostra como usar as classes no SDK do Open XML para inserir um novo slide em uma apresentação programaticamente.

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 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 leitura/gravação, especifique o valor verdadeiro para esse parâmetro, conforme mostrado na instrução de uso a seguir. Neste segmento de código, o parâmetro presentationFile é uma cadeia de caracteres que representa o caminho completo para o arquivo do qual você deseja abrir o documento.

    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        // 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.

Código de exemplo

Usando o código de exemplo, você pode adicionar um novo slide a uma apresentação existente. Em seu programa, você pode usar a chamada a seguir para o método InsertNewSlide para adicionar um novo slide a um arquivo de apresentação chamado "Myppt10.pptx", com o título "Meu novo slide", na posição 1.

    InsertNewSlide(@"C:\Users\Public\Documents\Myppt10.pptx", 1, "My new slide");

Depois de executar o programa, o novo slide será exibido como o segundo slide da apresentação.

Este é o código de exemplo completo em C# e em Visual Basic.


using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using Drawing = DocumentFormat.OpenXml.Drawing;

InsertNewSlide(args[0], int.Parse(args[1]), args[2]);

// Insert a slide into the specified presentation.
static void InsertNewSlide(string presentationFile, int position, string slideTitle)
{
    // Open the source document as read/write. 
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        // Pass the source document and the position and title of the slide to be inserted to the next method.
        InsertNewSlideFromPresentation(presentationDocument, position, slideTitle);
    }
}

// Insert the specified slide into the presentation at the specified position.
static void InsertNewSlideFromPresentation(PresentationDocument presentationDocument, int position, string slideTitle)
{
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    // Verify that the presentation is not empty.
    if (presentationPart is null)
    {
        throw new InvalidOperationException("The presentation document is empty.");
    }

    // Declare and instantiate a new slide.
    Slide slide = new Slide(new CommonSlideData(new ShapeTree()));
    uint drawingObjectId = 1;

    // Construct the slide content.            
    // Specify the non-visual properties of the new slide.
    CommonSlideData commonSlideData = slide.CommonSlideData ?? slide.AppendChild(new CommonSlideData());
    ShapeTree shapeTree = commonSlideData.ShapeTree ?? commonSlideData.AppendChild(new ShapeTree());
    NonVisualGroupShapeProperties nonVisualProperties = shapeTree.AppendChild(new NonVisualGroupShapeProperties());
    nonVisualProperties.NonVisualDrawingProperties = new NonVisualDrawingProperties() { Id = 1, Name = "" };
    nonVisualProperties.NonVisualGroupShapeDrawingProperties = new NonVisualGroupShapeDrawingProperties();
    nonVisualProperties.ApplicationNonVisualDrawingProperties = new ApplicationNonVisualDrawingProperties();

    // Specify the group shape properties of the new slide.
    shapeTree.AppendChild(new GroupShapeProperties());

    // Declare and instantiate the title shape of the new slide.
    Shape titleShape = shapeTree.AppendChild(new Shape());

    drawingObjectId++;

    // Specify the required shape properties for the title shape. 
    titleShape.NonVisualShapeProperties = new NonVisualShapeProperties
        (new NonVisualDrawingProperties() { Id = drawingObjectId, Name = "Title" },
        new NonVisualShapeDrawingProperties(new Drawing.ShapeLocks() { NoGrouping = true }),
        new ApplicationNonVisualDrawingProperties(new PlaceholderShape() { Type = PlaceholderValues.Title }));
    titleShape.ShapeProperties = new ShapeProperties();

    // Specify the text of the title shape.
    titleShape.TextBody = new TextBody(new Drawing.BodyProperties(),
            new Drawing.ListStyle(),
            new Drawing.Paragraph(new Drawing.Run(new Drawing.Text() { Text = slideTitle })));

    // Declare and instantiate the body shape of the new slide.
    Shape bodyShape = shapeTree.AppendChild(new Shape());
    drawingObjectId++;

    // Specify the required shape properties for the body shape.
    bodyShape.NonVisualShapeProperties = new NonVisualShapeProperties(new NonVisualDrawingProperties() { Id = drawingObjectId, Name = "Content Placeholder" },
            new NonVisualShapeDrawingProperties(new Drawing.ShapeLocks() { NoGrouping = true }),
            new ApplicationNonVisualDrawingProperties(new PlaceholderShape() { Index = 1 }));
    bodyShape.ShapeProperties = new ShapeProperties();

    // Specify the text of the body shape.
    bodyShape.TextBody = new TextBody(new Drawing.BodyProperties(),
            new Drawing.ListStyle(),
            new Drawing.Paragraph());

    // Create the slide part for the new slide.
    SlidePart slidePart = presentationPart.AddNewPart<SlidePart>();

    // Save the new slide part.
    slide.Save(slidePart);

    // Modify the slide ID list in the presentation part.
    // The slide ID list should not be null.
    SlideIdList? slideIdList = presentationPart.Presentation.SlideIdList;

    // Find the highest slide ID in the current list.
    uint maxSlideId = 1;
    SlideId? prevSlideId = null;

    OpenXmlElementList slideIds = slideIdList?.ChildElements ?? default;

    foreach (SlideId slideId in slideIds)
    {
        if (slideId.Id is not null && slideId.Id > maxSlideId)
        {
            maxSlideId = slideId.Id;
        }

        position--;
        if (position == 0)
        {
            prevSlideId = slideId;
        }

    }

    maxSlideId++;

    // Get the ID of the previous slide.
    SlidePart lastSlidePart;

    if (prevSlideId is not null && prevSlideId.RelationshipId is not null)
    {
        lastSlidePart = (SlidePart)presentationPart.GetPartById(prevSlideId.RelationshipId!);
    }
    else
    {
        string? firstRelId = ((SlideId)slideIds[0]).RelationshipId;
        // If the first slide does not contain a relationship ID, throw an exception.
        if (firstRelId is null)
        {
            throw new ArgumentNullException(nameof(firstRelId));
        }

        lastSlidePart = (SlidePart)presentationPart.GetPartById(firstRelId);
    }

    // Use the same slide layout as that of the previous slide.
    if (lastSlidePart.SlideLayoutPart is not null)
    {
        slidePart.AddPart(lastSlidePart.SlideLayoutPart);
    }

    // Insert the new slide into the slide list after the previous slide.
    SlideId newSlideId = slideIdList!.InsertAfter(new SlideId(), prevSlideId);
    newSlideId.Id = maxSlideId;
    newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);

    // Save the modified presentation.
    presentationPart.Presentation.Save();
}