Share via


Eliminar todos los comentarios de un autor de todas las diapositivas de una presentación

En este tema se muestra cómo usar las clases del SDK de Open XML para Office para eliminar todos los comentarios de un autor específico en una presentación mediante programación.

Obtención de un objeto PresentationDocument

En Open XML SDK, la clase PresentationDocument representa un paquete de documentos de presentación. Para trabajar con un documento de presentación, debe crear primero una instancia de la clase PresentationDocument y, a continuación, trabajar con esa instancia. Para crear la instancia de clase a partir del documento, llame al método Open(String, Boolean) que usa una ruta de acceso de archivo y un valor booleano como segundo parámetro para especificar si un documento es editable. Para abrir un documento en modo de lectura y escritura, especifique el valor true para este parámetro, como se muestra en la siguiente instrucción using. En este código, el parámetro fileName es una cadena que representa la ruta de acceso del archivo a partir del cual desea abrir el documento y el autor es el nombre de usuario mostrado en la pestaña General de Opciones de PowerPoint.

    public static void DeleteCommentsByAuthorInPresentation(string fileName, string author)
    {
        using (PresentationDocument doc = PresentationDocument.Open(fileName, true))
        {
            // Insert other code here.
        }

La instrucción using proporciona una alternativa recomendada a la típica secuencia .Open, .Save, .Close. Garantiza que se llamará automáticamente al método Dispose (un método interno que Open XML SDK usa para limpiar recursos) cuando se llegue a la llave de cierre. El bloque que sigue a la instrucción using establece un ámbito para el objeto que se crea o se nombra en la instrucción using, en este caso doc.

Estructura básica de un documento de presentación

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

La parte principal de un paquete PresentationML 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 documento PresentationML puede incluir son las siguientes: animación, audio, vídeo y transiciones entre diapositivas .

Los documentos PresentationML no se almacenan como un gran cuerpo en una sola parte. En su lugar, los elementos que implementan ciertas agrupaciones de funcionalidades se almacenan en partes independientes. Por ejemplo, todos los comentarios de un documento se almacenan en una parte de comentarios mientras que cada diapositiva cuenta con su propia parte.

© ISO/IEC29500: 2008.

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 DocumentFormat.OpenXml.Presentation . En la tabla siguiente se enumeran los nombres de las clases que corresponden a los elementos sld, sldLayout, sldMaster y notesMaster.

Elemento de PresentationML Open XML SDK (clase) Descripción
Sld Diapositiva 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.

Estructura del elemento Comment

El siguiente texto de la especificación ISO/IEC 29500 presenta los comentarios de un paquete de presentación.

Un comentario es una nota de texto adjunta a la diapositiva y su objetivo principal consiste en permitir a los lectores de una presentación proporcionar comentarios al autor de ésta. Cada comentario contiene una cadena de texto sin formato e información acerca del autor y está adjunto en una ubicación concreta de la diapositiva. Los comentarios pueden verse al editar la presentación, pero no al mostrarla. La aplicación que muestra la presentación decide cuándo mostrar los comentarios y determina su apariencia visual.

© ISO/IEC29500: 2008.

El siguiente elemento XML especifica un solo comentario adjunto a una diapositiva. Contiene el texto del comentario (text), su posición en la diapositiva (pos) y los atributos que hacen referencia al autor (authorId), la fecha y hora (dt) y el índice de comentarios (idx).

    <p:cm authorId="0" dt="2006-08-28T17:26:44.129" idx="1">
        <p:pos x="10" y="10"/>
        <p:text>Add diagram to clarify.</p:text>
    </p:cm>

En la siguiente tabla se enumeran las definiciones de los miembros y atributos del elemento cm (comentario).

Miembro o atributo Definición
authorId Hace referencia al identificador de un autor de la lista de autores de comentarios del documento.
Despegue Fecha y hora en que se modificó por última vez este comentario.
Idx Un identificador de este comentario que es exclusivo dentro de una lista de comentarios realizados por este autor en este documento. El primer comentario de un autor en un documento tiene el índice 1.
Pos La información de posicionamiento de la selección de ubicación de un comentario en la superficie de una diapositiva.
text Contenido de texto del comentario.
extLst Especifica la lista de extensiones con capacidad de modificación en la que se definen todas las extensiones futuras del tipo de elemento ext. La lista de extensiones, junto con las extensiones futuras correspondientes, se usa para ampliar las capacidades de almacenamiento del marco PresentationML. Esto permite que se almacenen en el marco diversos tipos de datos nuevos de forma nativa.

El siguiente ejemplo de esquema XML define los miembros del elemento cm además de los atributos opcionales y obligatorios.

    <complexType name="CT_Comment">
       <sequence>
           <element name="pos" type="a:CT_Point2D" minOccurs="1" maxOccurs="1"/>
           <element name="text" type="xsd:string" minOccurs="1" maxOccurs="1"/>
           <element name="extLst" type="CT_ExtensionListModify" minOccurs="0" maxOccurs="1"/>
       </sequence>
       <attribute name="authorId" type="xsd:unsignedInt" use="required"/>
       <attribute name="dt" type="xsd:dateTime" use="optional"/>
       <attribute name="idx" type="ST_Index" use="required"/>
    </complexType>

Funcionamiento del código de ejemplo

Una vez abierto el documento de presentación para acceso de lectura y escritura y creada una instancia de la clase PresentationDocument, el código obtiene el autor del comentario especificado de la lista de autores de comentarios.

    // Get the specifed comment author.
    IEnumerable<CommentAuthor> commentAuthors = 
        doc.PresentationPart.CommentAuthorsPart.CommentAuthorList.Elements<CommentAuthor>()
        .Where(e => e.Name.Value.Equals(author));

Al procesar una iteración de los autores coincidentes y de todas las diapositivas de la presentación, el código obtiene todas las partes de diapositiva y la parte de comentarios de cada uno de ellos. Posteriormente, obtiene la lista de comentarios del autor especificado y los elimina. También comprueba que no existen comentarios en la parte de comentarios, en cuyo caso elimina dicha parte. Además, elimina el autor del comentario de la parte de autores de comentarios.

    // Iterate through all the matching authors.
    foreach (CommentAuthor commentAuthor in commentAuthors)
    {
        UInt32Value authorId = commentAuthor.Id;

        // Iterate through all the slides and get the slide parts.
        foreach (SlidePart slide in doc.PresentationPart.SlideParts)
        {
            SlideCommentsPart slideCommentsPart = slide.SlideCommentsPart;
            // Get the list of comments.
            if (slideCommentsPart != null && slide.SlideCommentsPart.CommentList != null)
            {
                IEnumerable<Comment> commentList = 
                    slideCommentsPart.CommentList.Elements<Comment>().Where(e => e.AuthorId == authorId.Value);
                List<Comment> comments = new List<Comment>();
                comments = commentList.ToList<Comment>();

                foreach (Comment comm in comments)
                {
                    // Delete all the comments by the specified author.
                    slideCommentsPart.CommentList.RemoveChild<Comment>(comm);
                }

                // If the commentPart has no existing comment.
                if (slideCommentsPart.CommentList.ChildElements.Count == 0)
                    // Delete this part.
                    slide.DeletePart(slideCommentsPart);
            }
        }
        // Delete the comment author from the comment authors part.
        doc.PresentationPart.CommentAuthorsPart.CommentAuthorList.RemoveChild<CommentAuthor>(commentAuthor);
    }

Código de ejemplo

El siguiente método toma como parámetros el nombre de archivo de la presentación original y su ruta de acceso, y el nombre del autor cuyos comentarios se desea eliminar. Busca en la presentación todos los comentarios del autor especificado y los elimina. A continuación, elimina el autor de la lista de autores de comentarios.

Puede usar el siguiente ejemplo para llamar al método DeleteCommentsByAuthorInPresentation para que elimine los comentarios del autor especificado del archivo de presentación myppt5.pptx.

    string fileName = @"C:\Users\Public\Documents\myppt5.pptx";
    string author = "Katie Jordan";
    DeleteCommentsByAuthorInPresentation(fileName, author);

Nota:

[!NOTA] Para obtener el nombre exacto del autor, abra el archivo de presentación, haga clic en el elemento de menú Archivo y, a continuación, elija Opciones. Se abrirá la ventana Opciones de PowerPoint y se mostrará el contenido de la pestaña General. El nombre del autor debe coincidir con el Nombre de usuario que aparece en esta pestaña.

A continuación se incluye el código de ejemplo completo en C# y Visual Basic.

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System.Collections.Generic;
using System.Linq;

DeleteCommentsByAuthorInPresentation(args[0], args[1]);

// Remove all the comments in the slides by a certain author.
static void DeleteCommentsByAuthorInPresentation(string fileName, string author)
{
    using (PresentationDocument doc = PresentationDocument.Open(fileName, true))
    {
        // Get the specified comment author.
        IEnumerable<CommentAuthor>? commentAuthors = doc.PresentationPart?.CommentAuthorsPart?.CommentAuthorList?.Elements<CommentAuthor>()
            .Where(e => e.Name is not null && e.Name.Value is not null && e.Name.Value.Equals(author));

        if (commentAuthors is null)
        {
            return;
        }

        // Iterate through all the matching authors.
        foreach (CommentAuthor commentAuthor in commentAuthors)
        {
            UInt32Value? authorId = commentAuthor.Id;
            IEnumerable<SlidePart>? slideParts = doc.PresentationPart?.SlideParts;

            // If there's no author ID or slide parts, return.
            if (authorId is null || slideParts is null)
            {
                return;
            }

            // Iterate through all the slides and get the slide parts.
            foreach (SlidePart slide in slideParts)
            {
                SlideCommentsPart? slideCommentsPart = slide.SlideCommentsPart;

                // Get the list of comments.
                if (slideCommentsPart is not null && slide.SlideCommentsPart?.CommentList is not null)
                {
                    IEnumerable<Comment> commentList = slideCommentsPart.CommentList.Elements<Comment>().Where(e => e.AuthorId is not null && e.AuthorId == authorId.Value);
                    List<Comment> comments = new List<Comment>();
                    comments = commentList.ToList<Comment>();

                    foreach (Comment comm in comments)
                    {
                        // Delete all the comments by the specified author.

                        slideCommentsPart.CommentList.RemoveChild<Comment>(comm);
                    }

                    // If the commentPart has no existing comment.
                    if (slideCommentsPart.CommentList.ChildElements.Count == 0)
                        // Delete this part.
                        slide.DeletePart(slideCommentsPart);
                }
            }
            // Delete the comment author from the comment authors part.
            doc.PresentationPart?.CommentAuthorsPart?.CommentAuthorList.RemoveChild(commentAuthor);
        }
    }
}