Compartilhar via


Excluir slide de uma apresentação

Este tópico mostra como utilizar o SDK Open XML para o Office para eliminar um diapositivo de uma apresentação através de programação. Também mostra como eliminar todas as referências ao diapositivo de quaisquer apresentações personalizadas que possam existir. Para eliminar um diapositivo específico num ficheiro de apresentação, tem de saber primeiro o número de diapositivos na apresentação. Por conseguinte, o código neste procedimento está dividido em duas partes. O primeiro é contar o número de diapositivos e o segundo é eliminar um diapositivo num índice específico.

Observação

Eliminar um diapositivo de apresentações mais complexas, como as que contêm definições de vista de destaques, por exemplo, pode exigir passos adicionais.


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 uma das sobrecargas do Open método. O código neste tópico utiliza o Open método , que utiliza um caminho de ficheiro como o primeiro parâmetro para especificar o ficheiro a abrir e um valor Booleano como segundo parâmetro para especificar se um documento é editável. Defina este segundo parâmetro para false abrir o ficheiro para acesso só de leitura ou true se quiser abrir o ficheiro para acesso de leitura/escrita. O código neste tópico abre o ficheiro duas vezes, uma vez para contar o número de diapositivos e uma vez para eliminar um diapositivo específico. Quando conta o número de diapositivos numa apresentação, é melhor abrir o ficheiro para acesso só de leitura para proteger o ficheiro contra escrita acidental. A seguinte using instrução abre o ficheiro para acesso só de leitura. Neste exemplo de 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))

Para eliminar um diapositivo do ficheiro de apresentação, abra-o para acesso de leitura/escrita, conforme mostrado na seguinte using instrução.

// Open the source document as read/write.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))

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.

Contar o Número de Diapositivos

O código de exemplo consiste em duas sobrecargas do CountSlides método . 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 CountSlide 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 a slideCount e devolve-a.

if (presentationDocument is null)
{
    throw new ArgumentNullException("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;

Eliminar um Diapositivo Específico

O código para eliminar um diapositivo utiliza duas sobrecargas do DeleteSlide método . O primeiro método sobrecarregado DeleteSlide utiliza dois parâmetros: uma cadeia que representa o nome e o caminho do ficheiro de apresentação e um número inteiro que representa a posição do índice baseado em zero do diapositivo a eliminar. Abre o ficheiro de apresentação para acesso de leitura/escrita, obtém um PresentationDocument objeto e, em seguida, transmite esse objeto e o número de índice para o próximo método sobrecarregado DeleteSlide , que executa a eliminação.

// Get the presentation object and pass it to the next DeleteSlide method.
static void DeleteSlide(string presentationFile, int slideIndex)
{
    // Open the source document as read/write.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        // Pass the source document and the index of the slide to be deleted to the next DeleteSlide method.
        DeleteSlide(presentationDocument, slideIndex);
    }
}

A primeira secção do segundo método sobrecarregado DeleteSlide utiliza o CountSlides método para obter o número de diapositivos na apresentação. Em seguida, obtém a lista de IDs de diapositivos na apresentação, identifica o diapositivo especificado na lista de diapositivos e remove o diapositivo da lista de diapositivos.

// Delete the specified slide from the presentation.
static void DeleteSlide(PresentationDocument presentationDocument, int slideIndex)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException(nameof(presentationDocument));
    }

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

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

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

    // Get the presentation from the presentation part.
    Presentation? presentation = presentationPart?.Presentation;

    // Get the list of slide IDs in the presentation.
    SlideIdList? slideIdList = presentation?.SlideIdList;

    // Get the slide ID of the specified slide
    SlideId? slideId = slideIdList?.ChildElements[slideIndex] as SlideId;

    // Get the relationship ID of the slide.
    string? slideRelId = slideId?.RelationshipId;

    // If there's no relationship ID, there's no slide to delete.
    if (slideRelId is null)
    {
        return;
    }

    // Remove the slide from the slide list.
    slideIdList!.RemoveChild(slideId);

A secção seguinte do segundo método sobrecarregado DeleteSlide remove todas as referências ao diapositivo eliminado de apresentações personalizadas. Faz isso iterando através da lista de apresentações personalizadas e através da lista de diapositivos em cada apresentação personalizada. Em seguida, declara e instancia uma lista ligada de entradas de lista de diapositivos e localiza referências ao diapositivo eliminado através do ID de relação desse diapositivo. Adiciona essas referências à lista de entradas da lista de diapositivos e, em seguida, remove cada uma dessas referências da lista de diapositivos da respetiva apresentação personalizada.

// Remove references to the slide from all custom shows.
if (presentation!.CustomShowList is not null)
{
    // Iterate through the list of custom shows.
    foreach (var customShow in presentation.CustomShowList.Elements<CustomShow>())
    {
        if (customShow.SlideList is not null)
        {
            // Declare a link list of slide list entries.
            LinkedList<SlideListEntry> slideListEntries = new LinkedList<SlideListEntry>();
            foreach (SlideListEntry slideListEntry in customShow.SlideList.Elements())
            {
                // Find the slide reference to remove from the custom show.
                if (slideListEntry.Id is not null && slideListEntry.Id == slideRelId)
                {
                    slideListEntries.AddLast(slideListEntry);
                }
            }

            // Remove all references to the slide from the custom show.
            foreach (SlideListEntry slideListEntry in slideListEntries)
            {
                customShow.SlideList.RemoveChild(slideListEntry);
            }
        }
    }
}

Por fim, o código elimina a parte do diapositivo do diapositivo eliminado.

// Get the slide part for the specified slide.
SlidePart slidePart = (SlidePart)presentationPart!.GetPartById(slideRelId);

// Remove the slide part.
presentationPart.DeletePart(slidePart);

Código de exemplo

A seguir está o código de exemplo completo em C# e em Visual Basic.

// Get the presentation object and pass it to the next CountSlides method.
static int CountSlides(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation to the next CountSlide method
        // and return the slide count.
        return CountSlides(presentationDocument);
    }
}

// Count the slides in the presentation.
static int CountSlides(PresentationDocument presentationDocument)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException("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;
}

// Get the presentation object and pass it to the next DeleteSlide method.
static void DeleteSlide(string presentationFile, int slideIndex)
{
    // Open the source document as read/write.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        // Pass the source document and the index of the slide to be deleted to the next DeleteSlide method.
        DeleteSlide(presentationDocument, slideIndex);
    }
}
// Delete the specified slide from the presentation.
static void DeleteSlide(PresentationDocument presentationDocument, int slideIndex)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException(nameof(presentationDocument));
    }

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

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

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

    // Get the presentation from the presentation part.
    Presentation? presentation = presentationPart?.Presentation;

    // Get the list of slide IDs in the presentation.
    SlideIdList? slideIdList = presentation?.SlideIdList;

    // Get the slide ID of the specified slide
    SlideId? slideId = slideIdList?.ChildElements[slideIndex] as SlideId;

    // Get the relationship ID of the slide.
    string? slideRelId = slideId?.RelationshipId;

    // If there's no relationship ID, there's no slide to delete.
    if (slideRelId is null)
    {
        return;
    }

    // Remove the slide from the slide list.
    slideIdList!.RemoveChild(slideId);

    // Remove references to the slide from all custom shows.
    if (presentation!.CustomShowList is not null)
    {
        // Iterate through the list of custom shows.
        foreach (var customShow in presentation.CustomShowList.Elements<CustomShow>())
        {
            if (customShow.SlideList is not null)
            {
                // Declare a link list of slide list entries.
                LinkedList<SlideListEntry> slideListEntries = new LinkedList<SlideListEntry>();
                foreach (SlideListEntry slideListEntry in customShow.SlideList.Elements())
                {
                    // Find the slide reference to remove from the custom show.
                    if (slideListEntry.Id is not null && slideListEntry.Id == slideRelId)
                    {
                        slideListEntries.AddLast(slideListEntry);
                    }
                }

                // Remove all references to the slide from the custom show.
                foreach (SlideListEntry slideListEntry in slideListEntries)
                {
                    customShow.SlideList.RemoveChild(slideListEntry);
                }
            }
        }
    }

    // Get the slide part for the specified slide.
    SlidePart slidePart = (SlidePart)presentationPart!.GetPartById(slideRelId);

    // Remove the slide part.
    presentationPart.DeletePart(slidePart);
}

Confira também