Compartir a través de


Eliminar una diapositiva de una presentación

En este tema se muestra cómo usar el SDK de Open XML para Office para eliminar una diapositiva de una presentación mediante programación. Además, se muestra cómo eliminar todas las referencias a la diapositiva de todas las presentaciones personalizadas que puedan existir. Para eliminar una diapositiva específica de un archivo de presentación, debe conocer el número de diapositivas que esta contiene. Por lo tanto, el código de este procedimiento se divide en dos partes. La primera cuenta el número de diapositivas y la segunda elimina la diapositiva de un determinado índice.

Nota:

[!NOTA] Para eliminar una diapositiva de presentaciones más complejas, como aquellas que tienen configuración de vista en esquema, es posible que deban llevarse a cabo pasos adicionales.


Obtención de un objeto Presentation

En el SDK de Open XML, la PresentationDocument clase representa un paquete de documento de presentación. Para trabajar con un documento de presentación, cree primero una instancia de la PresentationDocument clase y, a continuación, trabaje con esa instancia. Para crear la instancia de clase a partir del documento, llame a una de las sobrecargas del Open método. El código de este tema usa el Open método , que toma una ruta de acceso de archivo como primer parámetro para especificar el archivo que se va a abrir, y un valor booleano como segundo parámetro para especificar si un documento es editable. Establezca este segundo parámetro false en para abrir el archivo para el acceso de solo lectura o true si desea abrir el archivo para el acceso de lectura y escritura. El código en este tema abre el archivo dos veces, una vez para contar el número de diapositivas y otra vez para eliminar una determinada diapositiva. Cuando cuente el número de diapositivas de una presentación, se recomienda abrir el archivo con acceso de solo lectura para evitar escribir accidentalmente el archivo. La instrucción siguiente using abre el archivo para el acceso de solo lectura. En este ejemplo de código, el presentationFile parámetro es una cadena que representa la ruta de acceso del archivo desde el que desea abrir el documento.

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

Para eliminar una diapositiva del archivo de presentación, ábrala para obtener acceso de lectura y escritura, como se muestra en la siguiente using instrucción.

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

Con v3.0.0+ el Close() método se ha quitado en favor de confiar en la instrucción using. Esto garantiza que se llama automáticamente al Dispose() método cuando se alcanza la llave de cierre. El bloque que sigue a la using instrucción establece un ámbito para el objeto que se crea o se denomina en la using instrucción , en este caso presentationDocument.

Estructura básica de un documento de presentación

La estructura básica de un PresentationML documento consta de varias partes, entre las que se encuentra la parte principal que contiene la definición de presentación. El siguiente texto de la especificación ISO/IEC 29500 presenta la forma general de un PresentationML paquete.

La parte principal de un PresentationML paquete comienza con un elemento raíz de presentación. Dicho elemento contiene una presentación que, a su vez, hace referencia a una lista de diapositivas, a otra de patrones de diapositivas, a otra de patrones de notas y a otra de patrones de documentos. La lista de diapositivas hace referencia a todas las diapositivas de la presentación, la de patrones de diapositivas a todos los patrones de diapositivas que se han usado en la presentación, el patrón de notas contiene información acerca del formato de las páginas de notas y el patrón de documentos describe la apariencia de los documentos.

Un documento es un conjunto impreso de diapositivas que se pueden proporcionar a un público.

Al igual que el texto y los gráficos, cada diapositiva puede incluir comentarios y notas, tener un diseño y formar parte de una o varias presentaciones personalizadas. Un comentario es una anotación dirigida a la persona que se encarga del mantenimiento de las diapositivas de la presentación. Una nota es un aviso o texto dirigido al moderador o al público.

Otras características que un PresentationML documento puede incluir son las siguientes: animación, audio, vídeo y transiciones entre diapositivas .

Un PresentationML documento no se almacena como un cuerpo grande en una sola parte. En su lugar, los elementos que implementan ciertas agrupaciones de funcionalidades se almacenan en partes independientes. Por ejemplo, todos los autores de un documento se almacenan en una parte de autores mientras que cada diapositiva tiene su propia parte.

ISO/IEC 29500: 2016

El siguiente ejemplo de código XML representa una presentación que contiene dos diapositivas denotadas por los identificadores 267 y 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>

Con el SDK de Open XML, puede crear contenido y estructura de documentos mediante clases fuertemente tipadas que corresponden a elementos PresentationML. Puede encontrar estas clases en el espacio de nombres. En la tabla siguiente se enumeran los nombres de clase de las clases correspondientes a los sldelementos , sldLayout, sldMastery notesMaster .

Elemento de PresentationML Open XML SDK (clase) Descripción
<sld/> Slide Diapositiva de presentación. Es el elemento raíz de SlidePart.
<sldLayout/> SlideLayout Diseño de la diapositiva. Es el elemento raíz de SlideLayoutPart.
<sldMaster/> SlideMaster Patrón de diapositivas. Es el elemento raíz de SlideMasterPart.
<notesMaster/> NotesMaster Patrón de notas (o handoutMaster). Es el elemento raíz de NotesMasterPart.

Recuento del número de diapositivas

El código de ejemplo consta de dos sobrecargas del CountSlides método . La primera sobrecarga usa un string parámetro y la segunda sobrecarga usa un PresentationDocument parámetro . En el primer CountSlides método, el código de ejemplo abre el documento de presentación en la using instrucción . A continuación, pasa el PresentationDocument objeto al segundo CountSlides método, que devuelve un número entero que representa el número de diapositivas de la presentación.

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

En el segundo CountSlides método, el código comprueba que el PresentationDocument objeto pasado no nulles y, si no es así, obtiene un PresentationPart objeto del PresentationDocument objeto . Mediante el uso del SlideParts código obtiene el slideCount y lo devuelve.

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;

Eliminación de una diapositiva específica

El código para eliminar una diapositiva usa dos sobrecargas del DeleteSlide método . El primer método sobrecargado DeleteSlide toma dos parámetros: una cadena que representa el nombre y la ruta de acceso del archivo de presentación y un entero que representa la posición de índice de base cero de la diapositiva que se va a eliminar. Abre el archivo de presentación para el acceso de lectura y escritura, obtiene un PresentationDocument objeto y, a continuación, pasa ese objeto y el número de índice al siguiente método sobrecargado DeleteSlide , que realiza la eliminación.

// 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);
    }
}

La primera sección del segundo método sobrecargado DeleteSlide usa el CountSlides método para obtener el número de diapositivas de la presentación. A continuación, obtiene la lista de identificadores de diapositivas de la presentación, identifica la diapositiva especificada y la quita de la lista de diapositivas.

// 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);

En la sección siguiente del segundo método sobrecargado se DeleteSlide quitan todas las referencias a la diapositiva eliminada de los programas personalizados. Se consigue mediante la iteración de la lista de presentaciones personalizadas y la lista de diapositivas en cada presentación personalizada. A continuación, declara y crea una instancia de una lista vinculada de entradas de listas de diapositivas y busca las referencias a la diapositiva eliminada mediante el identificador de relación de esa diapositiva. Agrega las referencias a la lista de entradas de listas de diapositivas y, a continuación, quita dicha referencia de cada en la lista de la diapositiva de la presentación personalizada correspondiente.

// 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 último, el código elimina la parte de diapositiva de la diapositiva eliminada.

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

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

Código de ejemplo

A continuación se incluye el código de ejemplo completo en C# y 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);
}

Recursos adicionales