Insérer un commentaire dans un document de traitement de texte
Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office afin d’ajouter par programmation un commentaire au premier paragraphe d’un document de traitement de texte.
Ouvrir le document existant en mode édition
Pour ouvrir un document existant, instanciez la WordprocessingDocument classe comme indiqué dans l’instruction suivante using
. Dans la même instruction, ouvrez le fichier de traitement de texte au chemin d’accès de fichier spécifié à l’aide de la Open(String, Boolean) méthode , avec le paramètre booléen défini sur true
pour permettre la modification dans le document.
using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
Avec v3.0.0+ la Close() méthode a été supprimée au profit de l’instruction using.
Il garantit que la Dispose() méthode est automatiquement appelée lorsque l’accolade fermante est atteinte. Le bloc qui suit l’instruction using établit une étendue pour l’objet créé ou nommé dans l’instruction using. Étant donné que la WordprocessingDocument classe du Kit de développement logiciel (SDK) Open XML enregistre et ferme automatiquement l’objet dans le cadre de son IDisposable implémentation, et que Dispose() est appelée automatiquement lorsque vous quittez le bloc, vous n’avez pas à appeler Save() explicitement ou Dispose() tant que vous utilisez une using
instruction.
Fonctionnement de l’exemple de code
Après ouverture du document, vous pouvez rechercher le premier paragraphe pour y joindre un commentaire. Le code recherche le premier paragraphe en appelant la méthode d’extension First sur tous les éléments descendants de l’élément document qui sont de type Paragraph. La First
méthode est membre de la Enumerable classe . La System.Linq.Enumerable
classe fournit des méthodes d’extension pour les objets qui implémentent l’interface IEnumerable<T> .
Paragraph firstParagraph = document.MainDocumentPart.Document.Descendants<Paragraph>().First();
wordprocessingCommentsPart.Comments ??= new Comments();
string id = "0";
Le code détermine d’abord si un WordprocessingCommentsPart composant existe. Pour ce faire, appelez la MainDocumentPart méthode générique , GetPartsCountOfType
et spécifiez un type de WordprocessingCommentsPart
.
S’il existe un WordprocessingCommentsPart
composant, le code obtient une nouvelle Id
valeur pour l’objet Comment qu’il ajoutera à l’objet de collection existant WordprocessingCommentsPart
Comments . Pour ce faire, il recherche la valeur d’attribut la plus élevée Id
donnée à un Comment
dans l’objet Comments
de collection, incrémente la valeur d’un, puis la stocke comme Id
valeur. S’il n’existe aucun WordprocessingCommentsPart
composant, le code en crée un à l’aide de la AddNewPart méthode de l’objet MainDocumentPart , puis y ajoute un Comments
objet de collection.
if (document.MainDocumentPart.GetPartsOfType<WordprocessingCommentsPart>().Count() > 0)
{
if (wordprocessingCommentsPart.Comments.HasChildren)
{
// Obtain an unused ID.
id = (wordprocessingCommentsPart.Comments.Descendants<Comment>().Select(e =>
{
if (e.Id is not null && e.Id.Value is not null)
{
return int.Parse(e.Id.Value);
}
else
{
throw new ArgumentNullException("Comment id and/or value are null.");
}
})
.Max() + 1).ToString();
}
}
Les Comment
objets et Comments
représentent les éléments commentaires et commentaires, respectivement, dans le schéma Wordprocessing Open XML. Un Comment
doit être ajouté à un Comments
objet afin que le code instancie d’abord un Comments
objet (à l’aide des arguments author
de chaîne , initials
et comments
qui ont été passés à la AddCommentOnFirstParagraph
méthode ).
Le commentaire est représenté par l’exemple de code WordprocessingML suivant. .
<w:comment w:id="1" w:initials="User">
...
</w:comment>
Le code ajoute ensuite le Comment
à l’objet Comments
. Cela crée l’arborescence DOM (Document Object Model) XML requise en mémoire, qui se compose d’un comments
élément parent avec comment
des éléments enfants sous celui-ci.
Paragraph p = new Paragraph(new Run(new Text(comment)));
Comment cmt =
new Comment()
{
Id = id,
Author = author,
Initials = initials,
Date = DateTime.Now
};
cmt.AppendChild(p);
wordprocessingCommentsPart.Comments.AppendChild(cmt);
L’exemple de code WordprocessingML suivant représente le contenu d’un composant commentaires dans un document WordprocessingML.
<w:comments>
<w:comment … >
…
</w:comment>
</w:comments>
Une fois l’objet Comment
instancié, le code associe le Comment
à une plage dans le document Wordprocessing.
CommentRangeStart Les objets et CommentRangeEnd correspondent aux commentRangeStart
éléments et commentRangeEnd
dans le schéma Wordprocessing Open XML.
Un CommentRangeStart
objet est donné comme argument à la InsertBefore méthode de l’objet Paragraph et un CommentRangeEnd
objet est passé à la InsertAfter méthode .
Cela crée une plage de commentaires dont l’étendue commence juste avant le premier caractère du premier paragraphe dans le document Wordprocessing et se termine juste après le dernier caractère du premier paragraphe.
Un CommentReference objet représente un commentReference
élément dans le schéma Wordprocessing Open XML. Un objet commentReference lie un commentaire spécifique dans la WordprocessingCommentsPart
partie (fichier Comments.xml dans le package Wordprocessing) à un emplacement spécifique dans le corps du document (partie MainDocumentPart
contenue dans le fichier Document.xml dans le package Wordprocessing). L’attribut id
du comment, commentRangeStart, commentRangeEnd et commentReference étant le même pour un commentaire donné, l’attribut commentReference id
doit correspondre à la valeur de l’attribut comment id
auquel il est lié. Dans l’exemple, le code ajoute un commentReference
élément à l’aide de l’API et instancie un CommentReference
objet, en spécifiant la Id
valeur, puis l’ajoute à un Run objet .
firstParagraph.InsertBefore(new CommentRangeStart()
{ Id = id }, firstParagraph.GetFirstChild<Run>());
// Insert the new CommentRangeEnd after last run of paragraph.
var cmtEnd = firstParagraph.InsertAfter(new CommentRangeEnd()
{ Id = id }, firstParagraph.Elements<Run>().Last());
// Compose a run with CommentReference and insert it.
firstParagraph.InsertAfter(new Run(new CommentReference() { Id = id }), cmtEnd);
Exemple de code
L’exemple de code suivant montre comment créer un commentaire et l’associer à une plage dans un document de traitement de texte. Pour appeler la méthode AddCommentOnFirstParagraph
, passez le chemin du document, votre nom, vos initiales et le texte du commentaire.
string fileName = args[0];
string author = args[1];
string initials = args[2];
string comment = args[3];
AddCommentOnFirstParagraph(fileName, author, initials, comment);
Voici un exemple de code complet en C# et Visual Basic.
// Insert a comment on the first paragraph.
static void AddCommentOnFirstParagraph(string fileName, string author, string initials, string comment)
{
// Use the file name and path passed in as an
// argument to open an existing Wordprocessing document.
using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
{
if (document.MainDocumentPart is null)
{
throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
}
WordprocessingCommentsPart wordprocessingCommentsPart = document.MainDocumentPart.WordprocessingCommentsPart ?? document.MainDocumentPart.AddNewPart<WordprocessingCommentsPart>();
// Locate the first paragraph in the document.
Paragraph firstParagraph = document.MainDocumentPart.Document.Descendants<Paragraph>().First();
wordprocessingCommentsPart.Comments ??= new Comments();
string id = "0";
// Verify that the document contains a
// WordProcessingCommentsPart part; if not, add a new one.
if (document.MainDocumentPart.GetPartsOfType<WordprocessingCommentsPart>().Count() > 0)
{
if (wordprocessingCommentsPart.Comments.HasChildren)
{
// Obtain an unused ID.
id = (wordprocessingCommentsPart.Comments.Descendants<Comment>().Select(e =>
{
if (e.Id is not null && e.Id.Value is not null)
{
return int.Parse(e.Id.Value);
}
else
{
throw new ArgumentNullException("Comment id and/or value are null.");
}
})
.Max() + 1).ToString();
}
}
// Compose a new Comment and add it to the Comments part.
Paragraph p = new Paragraph(new Run(new Text(comment)));
Comment cmt =
new Comment()
{
Id = id,
Author = author,
Initials = initials,
Date = DateTime.Now
};
cmt.AppendChild(p);
wordprocessingCommentsPart.Comments.AppendChild(cmt);
// Specify the text range for the Comment.
// Insert the new CommentRangeStart before the first run of paragraph.
firstParagraph.InsertBefore(new CommentRangeStart()
{ Id = id }, firstParagraph.GetFirstChild<Run>());
// Insert the new CommentRangeEnd after last run of paragraph.
var cmtEnd = firstParagraph.InsertAfter(new CommentRangeEnd()
{ Id = id }, firstParagraph.Elements<Run>().Last());
// Compose a run with CommentReference and insert it.
firstParagraph.InsertAfter(new Run(new CommentReference() { Id = id }), cmtEnd);
}
}