Compartilhar via


Mover um slide para uma nova posição em uma apresentação

Este tópico mostra como utilizar as classes no SDK Open XML para o Office para mover um diapositivo para uma nova posição numa apresentação programaticamente.


Obter um Objeto de Apresentação

No SDK Open XML, a PresentationDocument classe representa um pacote de documento de apresentação. Para trabalhar com um documento de apresentação, crie primeiro uma instância da PresentationDocument classe e, em seguida, trabalhe com essa instância. Para criar a instância de classe a partir do documento, chame o Open método que utiliza um caminho de ficheiro e um valor Booleano como segundo parâmetro para especificar se um documento é editável. Para contar o número de diapositivos numa apresentação, é melhor abrir o ficheiro para acesso só de leitura para evitar escrita acidental no ficheiro. Para tal, especifique o valor false para o parâmetro Booleano, conforme mostrado na seguinte using instrução. Neste código, o presentationFile parâmetro é uma cadeia que representa o caminho para o ficheiro a partir do qual pretende abrir o documento.

{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))

Com a v3.0.0+ o Close() método foi removido a favor de depender da instrução using. Isto garante que o Dispose() método é chamado automaticamente quando a chaveta de fecho é atingida. O bloco que segue a using instrução estabelece um âmbito para o objeto que é criado ou nomeado na using instrução , neste caso presentationDocument.


Estrutura básica do documento de apresentação

A estrutura de documentos básica de um PresentationML documento consiste em várias partes, entre as quais a main parte que contém a definição da apresentação. O texto seguinte da especificação ISO/IEC 29500 apresenta a forma geral de um PresentationML pacote.

O main parte de um PresentationML pacote 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 diapositivos, a uma lista de master de diapositivos, a uma lista de notas master e a um folheto master lista. A lista de diapositivos refere-se a todos os diapositivos na apresentação; A lista de master de diapositivos refere-se a todos os modelos globais de diapositivos utilizados na apresentação; as notas master contêm informações sobre a formatação das páginas de notas; e o master de folheto descreve o aspeto de um folheto.

Um folheto é um conjunto impresso de diapositivos que podem ser fornecidos a uma audiência.

Além de texto e gráficos, cada diapositivo pode conter comentários e notas, pode ter um esquema e pode fazer parte de uma ou mais apresentações personalizadas. Um comentário é uma anotação destinada à pessoa que mantém o conjunto de diapositivos da apresentação. Uma nota é um lembrete ou texto destinado ao apresentador ou à audiência.

Outras funcionalidades que um PresentationML documento pode incluir: animação, áudio, vídeo e transições entre diapositivos.

Um PresentationML documento não é armazenado como um corpo grande numa única parte. Em vez disso, os elementos que implementam determinados agrupamentos de funcionalidades são armazenados em partes separadas. Por exemplo, todos os autores num documento são armazenados numa parte dos autores, enquanto cada diapositivo tem a sua própria parte.

ISO/IEC 29500: 2016

O seguinte exemplo de código XML representa uma apresentação que contém dois diapositivos indicados pelos 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>

Com o SDK Open XML, pode criar a estrutura e o conteúdo do documento com classes com tipos fortes que correspondem a elementos PresentationML. Pode encontrar estas classes no espaço de nomes. A tabela seguinte lista os nomes das classes que correspondem aos sldelementos , sldLayout, sldMastere notesMaster .

Elemento PresentationML Abrir Classe SDK XML Descrição
<sld/> Slide Diapositivo de Apresentação. É o elemento raiz de SlidePart.
<sldLayout/> SlideLayout Esquema de Diapositivo. É o elemento raiz de SlideLayoutPart.
<sldMaster/> SlideMaster Modelo Global de Diapositivos. É o elemento raiz de SlideMasterPart.
<notesMaster/> NotesMaster Modelo Global de Notas (ou handoutMaster). É o elemento raiz de NotesMasterPart.

Como funciona o código de exemplo

Para mover um diapositivo específico num ficheiro de apresentação para uma nova posição, tem de saber primeiro o número de diapositivos na apresentação. Por conseguinte, o código neste tópico está dividido em duas partes. O primeiro é contar o número de diapositivos e o segundo está a mover um diapositivo para uma nova posição.


Contar o Número de Diapositivos

O código de exemplo para contar o número de diapositivos consiste em duas sobrecargas do método CountSlides. A primeira sobrecarga utiliza um string parâmetro e a segunda sobrecarga utiliza um PresentationDocument parâmetro. No primeiro CountSlides método, o código de exemplo abre o documento de apresentação na using instrução . Em seguida, transmite o PresentationDocument objeto para o segundo CountSlides método, que devolve um número inteiro que representa o número de diapositivos na apresentação.

// Pass the presentation to the next CountSlides method
// and return the slide count.
return CountSlides(presentationDocument);

No segundo CountSlides método, o código verifica se o PresentationDocument objeto transmitido não nullé e, se não for, obtém um PresentationPart objeto do PresentationDocument objeto. Ao utilizar o SlideParts código, obtém o e devolve-o slideCount .

int slidesCount = 0;

// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;

// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
    slidesCount = presentationPart.SlideParts.Count();
}

// Return the slide count to the previous method.
return slidesCount;

Mover um Diapositivo de uma Posição para Outra

Mover um diapositivo para uma nova posição requer abrir o ficheiro para acesso de leitura/escrita ao especificar o valor true para o parâmetro Booleano, conforme mostrado na instrução seguinte using . O código para mover um diapositivo consiste em duas sobrecargas do MoveSlide método . O primeiro método sobrecarregado MoveSlide utiliza três parâmetros: uma cadeia que representa o nome e o caminho do ficheiro de apresentação e dois números inteiros que representam a posição atual do índice do diapositivo e a posição do índice para o qual mover o diapositivo, respetivamente. Abre o ficheiro de apresentação, obtém um PresentationDocument objeto e, em seguida, transmite esse objeto e os dois números inteiros, from e to, para o segundo método sobrecarregado MoveSlide , que executa a movimentação real.

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}

No segundo método sobrecarregado MoveSlide , o CountSlides método é chamado para obter o número de diapositivos na apresentação. Em seguida, from o código verifica se os índices baseados em zero e to, estão dentro do intervalo e são diferentes uns dos outros.

// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Call the CountSlides method to get the number of slides in the presentation.
    int slidesCount = CountSlides(presentationDocument);

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }

Um PresentationPart objeto é declarado e definido como igual à parte da apresentação do PresentationDocument objeto transmitido. O PresentationPart objeto é utilizado para criar um Presentation objeto e, em seguida, criar um SlideIdList objeto que representa a lista de diapositivos na apresentação a Presentation partir do objeto. É obtido um ID de diapositivo do diapositivo de origem (o diapositivo a mover) e, em seguida, a posição do diapositivo de destino (o diapositivo após o qual a ordem do diapositivo para mover o diapositivo de origem) é identificada.

// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;

// The slide count is not zero, so the presentation must contain slides.            
Presentation? presentation = presentationPart?.Presentation;

if (presentation is null)
{
    throw new ArgumentNullException(nameof(presentation));
}

SlideIdList? slideIdList = presentation.SlideIdList;

if (slideIdList is null)
{
    throw new ArgumentNullException(nameof(slideIdList));
}

// Get the slide ID of the source slide.
SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;

if (sourceSlide is null)
{
    throw new ArgumentNullException(nameof(sourceSlide));
}

SlideId? targetSlide = null;

// Identify the position of the target slide after which to move the source slide.
if (to == 0)
{
    targetSlide = null;
}
else if (from < to)
{
    targetSlide = slideIdList.ChildElements[to] as SlideId;
}
else
{
    targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
}

O Remove método do SlideID objeto é utilizado para remover o diapositivo de origem da posição atual e, em seguida, o InsertAfter método do objeto é utilizado para inserir o diapositivo de SlideIdList origem na posição do índice após o diapositivo de destino. Por fim, a apresentação modificada é guardada.

// Remove the source slide from its current position.
sourceSlide.Remove();

// Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide);

Código de exemplo

Segue-se o código de exemplo completo que pode utilizar para mover um diapositivo de uma posição para outra no mesmo ficheiro de apresentação em C# e Visual Basic.

// Counting the slides in the presentation.
public static int CountSlides(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation to the next CountSlides method
        // and return the slide count.
        return CountSlides(presentationDocument);
    }
}

// Count the slides in the presentation.
static int CountSlides(PresentationDocument presentationDocument)
{
    int slidesCount = 0;

    // Get the presentation part of document.
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    // Get the slide count from the SlideParts.
    if (presentationPart is not null)
    {
        slidesCount = presentationPart.SlideParts.Count();
    }

    // Return the slide count to the previous method.
    return slidesCount;
}

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}

// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Call the CountSlides method to get the number of slides in the presentation.
    int slidesCount = CountSlides(presentationDocument);

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }

    // Get the presentation part from the presentation document.
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    // The slide count is not zero, so the presentation must contain slides.            
    Presentation? presentation = presentationPart?.Presentation;

    if (presentation is null)
    {
        throw new ArgumentNullException(nameof(presentation));
    }

    SlideIdList? slideIdList = presentation.SlideIdList;

    if (slideIdList is null)
    {
        throw new ArgumentNullException(nameof(slideIdList));
    }

    // Get the slide ID of the source slide.
    SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;

    if (sourceSlide is null)
    {
        throw new ArgumentNullException(nameof(sourceSlide));
    }

    SlideId? targetSlide = null;

    // Identify the position of the target slide after which to move the source slide.
    if (to == 0)
    {
        targetSlide = null;
    }
    else if (from < to)
    {
        targetSlide = slideIdList.ChildElements[to] as SlideId;
    }
    else
    {
        targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
    }
    // Remove the source slide from its current position.
    sourceSlide.Remove();

    // Insert the source slide at its new position after the target slide.
    slideIdList.InsertAfter(sourceSlide, targetSlide);
}

Confira também