💡 Exemple complet disponible sur GitHub :
extract-annotations-from-pdf-using-groupdocs-parser-dotnet
Introduction
Un PDF qui a été révisé contient généralement plus que son texte visible : notes autocollantes, remarques surlignées et commentaires en ligne laissés par les relecteurs. Faire défiler chaque page pour les trouver ne fonctionne pas lorsqu’un document a traversé plusieurs cycles de commentaires. GroupDocs.Parser est une bibliothèque .NET qui lit les annotations intégrées d’un document de façon programmatique, transformant les commentaires dispersés des relecteurs en données structurées que votre code peut exploiter. Ce tutoriel montre comment extraire les annotations d’un PDF complet, les détailler page par page, les associer au texte du document, puis exporter les résultats au format CSV ou JSON.
J’ai rencontré ce problème en construisant un suivi de révision pour une équipe de documentation : une note de version de 40 pages était passée par trois relecteurs, et ouvrir manuellement le fichier pour trouver chaque commentaire prenait plus de temps que de corriger les problèmes signalés. Extraire les annotations en quelques lignes de code a transformé cela en une tâche de deux minutes.
Dans les sections suivantes, vous apprendrez à :
- Extraire chaque annotation d’un PDF en un seul passage.
- Associer chaque annotation à la page à laquelle elle appartient.
- Récupérer le texte du document et le texte des annotations ensemble en une seule lecture.
- Sérialiser les résultats en CSV ou JSON pour les outils en aval.
Pourquoi extraire les annotations PDF est important
Lire les annotations PDF de façon programmatique est utile pour :
- Flux de travail de révision : collecter chaque commentaire de relecteur sans ouvrir le fichier dans un visualiseur PDF.
- Collaboration : mettre en avant les sections surlignées ou notées directement dans vos propres outils.
- Audit : conserver un enregistrement du balisage laissé sur un document au fil du temps, même après qu’il ait été aplati ou finalisé.
GroupDocs.Parser a ajouté l’extraction native des annotations pour les documents PDF dans la version 26.7 via la méthode GetAnnotations, ainsi qu’une nouvelle option IncludeAnnotations sur TextOptions pour intégrer le texte des annotations dans une lecture de texte ordinaire.
Prérequis
- .NET 6.0 ou version ultérieure
- GroupDocs.Parser for .NET 26.7+ (licence temporaire)
- Un fichier PDF contenant des annotations existantes (par ex.,
document-with-annotations.pdf)
Installation via NuGet :
dotnet add package GroupDocs.Parser
Comment extraire les annotations d’un document PDF ?
Réponse : Chargez le fichier avec Parser, puis appelez GetAnnotations() pour le document entier ou GetAnnotations(pageIndex) pour une page unique. Chaque résultat est une collection d’objets AnnotationItem dont la propriété Value contient le texte du commentaire. Si vous préférez voir les commentaires intégrés au contenu régulier du document, activez IncludeAnnotations sur TextOptions et appelez GetText à la place.
Extraction du document complet
L’extrait suivant récupère chaque annotation du fichier en un seul appel, ce qui est la façon la plus rapide de vérifier si un document possède des commentaires ouverts.
// Extract every annotation from the whole document
var result = new List<string>();
using (var parser = new Parser(path))
{
IEnumerable<AnnotationItem> annotations = parser.GetAnnotations();
if (annotations == null)
{
return result; // format doesn't support annotations
}
foreach (var item in annotations)
{
result.Add(item.Value); // annotation text
}
}
return result;
Points clés :
GetAnnotations()renvoienulllorsque l’extraction d’annotations n’est pas prise en charge pour le document, et une collection vide lorsque le document n’en possède tout simplement aucune.- Chaque
AnnotationItemexpose son texte via la propriétéValue— c’est le seul point de données que le SDK rapporte actuellement. - Aucune attribution de page n’est incluse ici ; utilisez la surcharge par page ci‑dessous si vous en avez besoin.
Extraction page par page
Lorsque l’emplacement d’un commentaire importe, parcourez les pages du document et appelez GetAnnotations(pageIndex) pour chacune d’elles.
// Tag each annotation with its zero-based page index
var result = new List<AnnotationRecord>();
using (var parser = new Parser(path))
{
if (!parser.Features.Annotations)
{
return result;
}
var info = parser.GetDocumentInfo();
if (info == null || info.PageCount == 0)
{
return result;
}
for (int pageIndex = 0; pageIndex < info.PageCount; pageIndex++)
{
IEnumerable<AnnotationItem> pageAnnotations = parser.GetAnnotations(pageIndex);
if (pageAnnotations == null)
{
continue;
}
foreach (var item in pageAnnotations)
{
result.Add(new AnnotationRecord { PageIndex = pageIndex, Value = item.Value });
}
}
}
return result;
Points clés :
GetDocumentInfo().PageCountpilote la boucle ; il n’existe pas de « compte de pages d’annotation ».GetAnnotations(pageIndex)utilise un indice zéro‑based, comme toutes les autres méthodes de niveau page de l’API.- La liste résultante
AnnotationRecorda exactement la forme requise pour une exportation CSV ou JSON.
Extraction du texte avec les annotations
Au lieu de deux passages sur le document, vous pouvez intégrer le texte des annotations directement dans la sortie d’extraction de texte ordinaire.
// Read document text with annotation text included
using (var parser = new Parser(path))
{
var options = new TextOptions
{
IncludeAnnotations = true
};
using (TextReader reader = parser.GetText(options))
{
return reader?.ReadToEnd() ?? string.Empty;
}
}
Points clés :
IncludeAnnotationsest une propriété deTextOptions, donc cela fonctionne avec le même appelGetTextque vous utilisez déjà pour l’extraction de texte brut.- Utile lorsque vous souhaitez une sortie de type transcription unique plutôt qu’une liste de commentaires séparée.
- Combinez‑le avec
GetText(pageIndex, options)si vous ne le voulez que pour une page.
Vérifier la prise en charge des annotations au préalable
Tous les formats ne supportent pas les annotations, il est donc judicieux de vérifier avant de bâtir une logique autour de GetAnnotations.
// Returns true if the loaded document format supports annotation extraction
using (var parser = new Parser(path))
{
return parser.Features.Annotations;
}
Points clés :
Features.Annotationsest un simple drapeau booléen sur l’instanceParser.- Le vérifier dès le départ rend l’intention explicite, même si
GetAnnotationséchoue déjà proprement en renvoyantnull.
Exportation des annotations au format CSV
Une exportation CSV permet aux relecteurs d’ouvrir la liste des commentaires directement dans Excel. La méthode ci‑dessous écrit un fichier à deux colonnes (page,value) à partir des enregistrements tagués par page créés précédemment.
var sb = new StringBuilder();
sb.AppendLine("page,value");
foreach (var record in records)
{
sb.AppendLine($"{record.PageIndex},{CsvEscape(record.Value)}");
}
File.WriteAllText(outputPath, sb.ToString());
Points clés :
CsvEscapecite en toute sécurité les champs contenant des virgules, des guillemets ou des sauts de ligne.- Le fichier résultant s’ouvre directement dans Excel ou peut être acheminé vers un outil de ticketing.
Helper : CsvEscape
if (string.IsNullOrEmpty(s)) return string.Empty;
if (s.Contains(",") || s.Contains("\"") || s.Contains("\n"))
{
return "\"" + s.Replace("\"", "\"\"") + "\"";
}
return s;
Exportation des annotations au format JSON
Pour les pipelines qui consomment les commentaires de façon programmatique, un tableau JSON est généralement plus adapté qu’un CSV plat.
var sb = new StringBuilder();
sb.AppendLine("[");
for (int i = 0; i < records.Count; i++)
{
var comma = i < records.Count - 1 ? "," : string.Empty;
sb.AppendLine($" {{ \"page\": {records[i].PageIndex}, \"value\": \"{Escape(records[i].Value)}\" }}{comma}");
}
sb.AppendLine("]");
File.WriteAllText(outputPath, sb.ToString());
Points clés :
- La sortie est un tableau plat d’objets
{ page, value }— facile à désérialiser pour n’importe quel service en aval. Escapemaintient la charge utile JSON valide sans faire appel à une bibliothèque de sérialisation.
Helper : Escape
return s?.Replace("\\", "\\\\").Replace("\"", "\\\"") ?? string.Empty;
Comparaison des méthodes : quand utiliser laquelle
| Méthode | Idéal pour | Principaux avantages | Limitations |
|---|---|---|---|
| Extraction du document complet | Vérification rapide « des commentaires existent‑t‑ils ? » | Un appel unique, code le plus simple | Pas d’attribution de page |
| Extraction page par page | Diriger les retours vers la bonne section | Résultats tagués par page, prêts à exporter | Un appel supplémentaire par page |
| Texte combiné + Annotations | Transcript unique lisible | Pas de second passage sur le document | Les commentaires ne sont pas séparés du texte principal |
| Export CSV | Suivi de révision basé sur tableur | Ouverture facile dans Excel, lisible par l’homme | Structure plate uniquement |
| Export JSON | Pipelines automatisés, systèmes de ticketing | Structuré, lisible par machine | Charge légèrement plus importante |
Commencez par l’extraction du document complet pour confirmer qu’un fichier possède des commentaires, puis passez à l’extraction page par page lorsque vous devez orienter le feedback vers une section précise.
Bonnes pratiques et astuces
- Libérez
Parserrapidement : encapsulez‑le dans un blocusingpour libérer les ressources natives. - Distinguisez
nulld’une collection vide :GetAnnotationsrenvoyantnullsignifie que le format n’est pas supporté ; une collection vide signifie que le document n’a aucun commentaire. - Vérifiez
Features.Annotationsdans les jobs batch : ignorez les fichiers non supportés dès le départ plutôt que de compter sur un testnullen profondeur de boucle. - Réutilisez la liste taguée par page : construisez‑la une fois avec
ExtractAnnotationsByPageet alimentez à la fois les exportateurs CSV et JSON à partir des mêmes données, afin que les deux sorties ne divergent jamais. - Sécurité : le texte des annotations est une entrée libre du relecteur – traitez‑le comme toute autre chaîne non fiable avant de l’afficher dans une UI ou un rapport.
Conclusion
GroupDocs.Parser vous offre un moyen direct et programmatique d’extraire les commentaires des relecteurs d’un PDF au lieu de les chercher manuellement. En extrayant les annotations pour le document entier, en les taguant par page ou en les intégrant au flux de texte ordinaire, vous pouvez créer des flux de travail de révision qui font remonter le feedback dès que le document entre dans votre pipeline. Exportez les résultats en CSV ou JSON et intégrez‑les directement aux outils déjà utilisés par votre équipe.
Prochaines étapes :
- Explorez la référence API GetAnnotations pour la signature complète de la méthode et ses surcharges.
- Apprenez comment extraire le texte des documents PDF en même temps que les annotations pour un pipeline de contenu complet.
- Consultez d’autres projets d’exemple sur GitHub pour des scénarios de traitement par lots (Exemples Repo).