Partager via


Supprimer tous les commentaires d’un auteur de toutes les diapositives d’une présentation

Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office afin de supprimer par programme tous les commentaires d’un auteur spécifique dans une présentation.

Obtention d’un objet PresentationDocument

Dans le Kit de développement logiciel (SDK) Open XML, la classe PresentationDocument représente un package de documents de présentation. Pour utiliser un document de présentation, créez d’abord une instance de la classe PresentationDocument, puis utilisez cette instance. Pour créer la classe instance à partir du document, appelez la méthode Open(String, Boolean) qui utilise un chemin d’accès de fichier et une valeur booléenne comme deuxième paramètre pour spécifier si un document est modifiable. Pour ouvrir un document en lecture/écriture, spécifiez la valeur true pour ce paramètre, comme indiqué dans l’instruction using suivante. Dans ce code, le paramètre fileName est une chaîne qui représente le chemin d’accès pour le fichier à partir duquel vous voulez ouvrir le document, et le paramètre author est le nom d’utilisateur affiché dans l’onglet Général des options PowerPoint.

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

L'instruction using offre une alternative recommandée pour la séquence .Open, .Save, .Close standard. Elle garantit que la méthode Dispose (méthode interne utilisée par le kit de développement Open XML pour nettoyer les ressources) est automatiquement appelée lorsque l'accolade de fermeture est atteinte. Le bloc qui suit l’instruction using établit une étendue pour l’objet créé ou nommé dans l’instruction using, dans le cas présent doc.

Structure de document de présentation de base

La structure de document de base d’un document PresentationML est constituée d’un certain nombre de composants, parmi lesquels le composant principal qui contient la définition de la présentation. Le texte suivant de la spécification ISO/IEC 29500 présente la forme globale d’un package PresentationML .

La partie main d’un package PresentationML commence par un élément racine de présentation. Cet élément contient une présentation qui, à son tour, fait référence à une liste de diapositives, à une liste de diapositives master, à une liste de notes master et à un document master liste. La liste des diapositives référence toutes les diapositives de la présentation ; la liste de masques de diapositive référence tous les masques de diapositive utilisés dans la présentation ; le masque de pages de note contient des informations sur la mise en forme des pages de notes et le masque de document décrit comment un document se présente.

Un document à distribuer est un ensemble imprimé de diapositives qui peut être distribué aux personnes de l’audience.

En plus de textes et de graphiques, chaque diapositive peut contenir des commentaires et des notes, peut avoir une disposition et peut faire partie d’une ou plusieurs présentations personnalisées. Un commentaire est une annotation destinée à la personne qui gère le jeu de diapositives de la présentation. Une note est un rappel ou un élément de texte destiné au présentateur ou à l’audience.

Les autres fonctionnalités qu’un document PresentationML peut inclure les suivantes : animation, audio, vidéo et transitions entre les diapositives.

Un document PresentationML n’est pas stocké sous la forme d’un corps de grande taille dans un même composant. Au lieu de cela, les éléments qui implémentent certains groupes de fonctionnalités sont stockés dans des composants distincts. Par exemple, tous les commentaires d’un document sont stockés dans un même composant Commentaires, alors que chaque diapositive a son propre composant.

© ISO/IEC29500: 2008.

L’exemple de code XML suivant représente une présentation qui contient deux diapositives ayant les numéros d’identification 267 et 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>

À l’aide du Kit de développement logiciel (SDK) Open XML, vous pouvez créer une structure de document et du contenu à l’aide de classes fortement typées qui correspondent aux éléments PresentationML. Vous trouverez ces classes dans l’espace de noms DocumentFormat.OpenXml.Presentation . Le tableau suivant répertorie les noms des classes qui correspondent aux éléments sld, sldLayout, sldMaster et notesMaster.

Élément PresentationML Classe du Kit de développement logiciel (SDK) Open XML Description
Sld Slide Diapositive de présentation. Il s’agit de l’élément racine de SlidePart.
sldLayout SlideLayout Mise en page des diapositives. Il s’agit de l’élément racine de SlideLayoutPart.
sldMaster SlideMaster Masque des diapositives. Il s’agit de l’élément racine de SlideMasterPart.
Notesmaster NotesMaster Masque des pages de notes (ou handoutMaster). Il s’agit de l’élément racine de NotesMasterPart.

La structure de l’élément de commentaire

Le texte suivant de la spécification ISO/IEC 29500 présente des commentaires dans un package de présentation.

Un commentaire est une note textuelle rattachée à une diapositive, ayant comme objectif principal de permettre aux lecteurs d’une présentation de fournir des commentaires à l’auteur de la présentation. Chaque commentaire contient une chaîne de texte non mise en forme et des informations sur son auteur, et elle est rattachée à un emplacement particulier sur une diapositive. Les commentaires peuvent être visibles lors de la modification de la présentation, mais ils n’apparaissent pas lors de l’exécution d’un diaporama. L’application d’affichage décide du moment où afficher les commentaires et détermine leur apparence visuelle.

© ISO/IEC29500: 2008.

L’élément XML suivant spécifie un seul commentaire rattaché à une diapositive. Il contient le texte du commentaire (text), sa position sur la diapositive (pos), ainsi que des attributs référençant son auteur (authorId), la date et l’heure (dt) et l’index du commentaire (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>

Le tableau suivant répertorie les définitions des membres et des attributs de l’élément cm (commentaire).

Membre/Attribut Définition
authorId Référence l’ID d’un auteur dans la liste des auteurs de commentaires pour le document.
Dt La date et l’heure à laquelle ce commentaire a été modifié pour la dernière fois.
Idx Un identificateur pour ce commentaire, unique dans une liste de tous les commentaires par cet auteur dans ce document. Le premier commentaire d’un auteur a l’index 1.
Pos Les informations de positionnement pour le placement d’un commentaire sur la surface d’une diapositive.
text Le contenu texte d’un commentaire.
extLst Spécifie la liste des extensions avec possibilité de modification dans laquelle toutes les extensions futures de type d’élément ext sont définies. La liste des extensions et les extensions futures correspondantes sont utilisées pour étendre les capacités de stockage de l’infrastructure PresentationML. Ceci permet à différents nouveaux types de données d’être stockés en mode natif dans l’infrastructure.

L’exemple de schéma XML suivant définit les membres de l’élément cm, ainsi que les attributs requis ou facultatifs.

    <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>

Fonctionnement de l’exemple de code

Après avoir ouvert le document de présentation en lecture/écriture et instancié la classe PresentationDocument, le code obtient l’auteur des commentaires spécifié à partir de la liste des auteurs de commentaires.

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

En itérant parmi les auteurs correspondants et les diapositives de la présentation, le code obtient tous les composants diapositive, ainsi que le composant commentaires de chacun. Il obtient ensuite la liste des commentaires de l’auteur spécifié et supprime chacun d’eux. Il vérifie si le composant commentaires ne contient aucun commentaire existant, auquel cas il le supprime. Il supprime également l’auteur des commentaires du composant auteurs de commentaires.

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

Exemple de code

La méthode suivante prend comme paramètres le nom et le chemin d’accès au fichier de présentation source et le nom de l’auteur dont les commentaires doivent être supprimés. Elle recherche tous les commentaires de l’auteur spécifié dans la présentation et les supprime. Elle supprime ensuite cet auteur de la liste des auteurs de commentaires.

Vous pouvez utiliser l’exemple suivant pour appeler la méthode DeleteCommentsByAuthorInPresentation afin de supprimer les commentaires de l’auteur spécifié du fichier de présentation myppt5.pptx.

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

Remarque

Pour obtenir le nom exact de l’auteur, ouvrez le fichier de présentation, cliquez sur l’élément de menu Fichier , puis cliquez sur Options. La fenêtre Options PowerPoint s’ouvre et le contenu de l’onglet Général s’affiche. Le nom de l’auteur doit correspondre au nom d’utilisateur de cet onglet.

Voici un exemple de code complet en C# et 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);
        }
    }
}