💡 Plně funkční příklad je k dispozici na GitHubu:
extract-annotations-from-pdf-using-groupdocs-parser-dotnet
Úvod
PDF, které prošlo revizí, obvykle obsahuje více než jen viditelný text – lepkavé poznámky, zvýrazněné připomínky a vložené komentáře od recenzentů. Procházet každou stránku a hledat je se nevyplatí, jakmile dokument prošel několika koly zpětné vazby. GroupDocs.Parser je .NET knihovna, která programově čte vložené anotace dokumentu a převádí rozptýlené komentáře recenzentů na strukturovaná data, se kterými může váš kód pracovat. Tento tutoriál ukazuje, jak extrahovat anotace z celého PDF, rozdělit je po stránkách, získat je společně s textem dokumentu a exportovat výsledky do CSV nebo JSON.
Na tento problém jsem narazil při tvorbě sledovače revizí pro tým dokumentace: 40‑stránková poznámka k vydání prošla třemi recenzenty a ruční otevírání souboru a hledání každého komentáře trvalo déle, než samotné opravy, které označili. Extrahování anotací několika řádky kódu to proměnilo v dvouminutovou práci.
V následujících sekcích se naučíte:
- Extrahovat každou anotaci z PDF v jednom průchodu.
- Označit každou anotaci stránkou, ke které patří.
- Získat text dokumentu a text anotace společně v jednom čtení.
- Serializovat výsledky do CSV nebo JSON pro další nástroje.
Proč je důležité extrahovat anotace z PDF
Programatické čtení anotací PDF je užitečné pro:
- Revizní workflow: Shromáždit každý komentář recenzenta bez otevírání souboru v PDF prohlížeči.
- Spolupráci: Zobrazit zvýrazněné nebo poznamenané úseky přímo ve vašich nástrojích.
- Audit: Uchovat záznam o poznámkách přidaných do dokumentu v čase, i po jeho zploštění nebo finalizaci.
GroupDocs.Parser přidal nativní extrakci anotací pro PDF dokumenty ve verzi 26.7 prostřednictvím metody GetAnnotations a novou možnost IncludeAnnotations v TextOptions pro zahrnutí textu anotací do běžného čtení textu.
Požadavky
- .NET 6.0 nebo novější
- GroupDocs.Parser pro .NET 26.7+ (dočasná licence)
- PDF soubor s existujícími anotacemi (např.
document-with-annotations.pdf)
Instalace přes NuGet:
dotnet add package GroupDocs.Parser
Jak extrahovat anotace z PDF dokumentu?
Odpověď: Načtěte soubor pomocí Parser a poté zavolejte GetAnnotations() pro celý dokument nebo GetAnnotations(pageIndex) pro jednotlivou stránku. Každý výsledek je kolekce objektů AnnotationItem, jejichž vlastnost Value obsahuje text komentáře. Pokud chcete vidět komentáře vložené do běžného obsahu dokumentu, nastavte IncludeAnnotations v TextOptions a místo toho zavolejte GetText.
Extrakce celého dokumentu
Následující úryvek získá každou anotaci ze souboru jedním voláním, což je nejrychlejší způsob, jak zjistit, zda dokument vůbec obsahuje otevřené komentáře.
// 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;
Klíčové body:
GetAnnotations()vracínull, když extrakce anotací pro dokument není podporována, a prázdnou kolekci, když dokument prostě žádné anotace nemá.- Každý
AnnotationItemposkytuje svůj text přes vlastnostValue– to je jediný datový bod, který SDK v současnosti poskytuje. - Žádná informace o stránce není zahrnuta; pokud ji potřebujete, použijte níže uvedený přetížený způsob pro jednotlivé stránky.
Extrakce po stránkách
Když záleží na umístění komentáře, projděte stránky dokumentu a pro každou zavolejte GetAnnotations(pageIndex).
// 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;
Klíčové body:
GetDocumentInfo().PageCountřídí smyčku; neexistuje samostatný „počet stránek s anotacemi“.GetAnnotations(pageIndex)používá nulový index, stejně jako všechny ostatní metody pracující se stránkami v API.- Výsledný seznam
AnnotationRecordmá přesně takový tvar, jaký potřebuje export do CSV nebo JSON.
Extrakce textu společně s anotacemi
Místo dvou průchodů dokumentem můžete vložit text anotací přímo do výstupu běžné extrakce textu.
// 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;
}
}
Klíčové body:
IncludeAnnotationsje vlastnost vTextOptions, takže to funguje se stejným volánímGetText, které už používáte pro čistý text.- Užitečné, když chcete jeden výstup ve stylu přepisu místo samostatného seznamu komentářů.
- Kombinujte s
GetText(pageIndex, options), pokud to potřebujete jen pro jednu stránku.
Kontrola podpory anotací předem
Ne každý formát podporuje anotace, proto je dobré to ověřit, než budete stavět logiku kolem GetAnnotations.
// Returns true if the loaded document format supports annotation extraction
using (var parser = new Parser(path))
{
return parser.Features.Annotations;
}
Klíčové body:
Features.Annotationsje jednoduchý boolean flag na instanciParser.- Ověření předem dělá záměr explicitní, i když
GetAnnotationsuž selže elegantně vrácenímnull.
Export anotací do CSV
Export do CSV umožní recenzentům otevřít seznam komentářů přímo v Excelu. Níže uvedená metoda zapíše dvousloupcový soubor (page,value) z dříve vytvořených záznamů s označením stránky.
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());
Klíčové body:
CsvEscapebezpečně uvozovku pole obsahující čárky, uvozovky nebo zalomení řádku.- Výsledný soubor se otevře přímo v Excelu nebo může být předán do ticketovacího nástroje.
Pomocná metoda: CsvEscape
if (string.IsNullOrEmpty(s)) return string.Empty;
if (s.Contains(",") || s.Contains("\"") || s.Contains("\n"))
{
return "\"" + s.Replace("\"", "\"\"") + "\"";
}
return s;
Export anotací do JSON
Pro pipeline, které konzumují komentáře programově, je JSON pole obvykle vhodnější než ploché CSV.
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());
Klíčové body:
- Výstup je ploché pole objektů
{ page, value }– snadno deserializovatelné libovolnou downstream službou. Escapeudržuje payload platný JSON bez nutnosti zavádět knihovnu pro serializaci.
Pomocná metoda: Escape
return s?.Replace("\\", "\\\\").Replace("\"", "\\\"") ?? string.Empty;
Porovnání metod: Kdy použít kterou
| Metoda | Nejlepší pro | Klíčové výhody | Omezení |
|---|---|---|---|
| Whole‑Document Extraction | Rychlé zjištění „jsou vůbec nějaké komentáře?“ | Jedno volání, nejjednodušší kód | Žádná informace o stránce |
| Per‑Page Extraction | Směrování zpětné vazby na správnou sekci | Výsledky s označením stránky, připravené k exportu | Jedno extra volání na stránku |
| Combined Text + Annotations | Jeden čitelný přepis | Žádný druhý průchod dokumentem | Komentáře nejsou odděleny od těla textu |
| CSV Export | Sledování revizí v tabulkovém procesoru | Snadno otevřitelné v Excelu, čitelné pro člověka | Omezeno na plochou strukturu |
| JSON Export | Automatizované pipeline, ticketovací systémy | Strukturované, strojově čitelné | O něco větší payload |
Začněte s extrakcí celého dokumentu, abyste potvrdili, že soubor obsahuje komentáře, které stojí za zpracování, a poté přejděte na extrakci po stránkách, pokud potřebujete směrovat zpětnou vazbu na konkrétní část.
Nejlepší postupy a tipy
- Okamžitě uvolňujte
Parser: zabalte jej dousingbloku, aby se uvolnily nativní zdroje. - Rozlišujte
nulla prázdné:GetAnnotationsvracínull, pokud formát není podporován; prázdná kolekce znamená, že dokument nemá žádné komentáře. - Kontrolujte
Features.Annotationsv dávkových úlohách: vynechejte nepodporované soubory hned na začátku místo spoléhaní se nanullkontrolu uvnitř smyčky. - Znovu použijte seznam s označením stránky: vytvořte jej jednou pomocí
ExtractAnnotationsByPagea použijte pro CSV i JSON exportéry ze stejných dat, aby výstupy nikdy neodchýlily. - Bezpečnost: text anotace je volně psaný vstup recenzenta – zacházejte s ním jako s jakýmkoli jiným nedůvěryhodným řetězcem před jeho vykreslením v UI nebo reportu.
Závěr
GroupDocs.Parser vám poskytuje přímý, programový způsob, jak vytáhnout komentáře recenzentů z PDF místo ručního hledání. Extrahováním anotací pro celý dokument, jejich označením podle stránky nebo vložením do běžného textového proudu můžete vytvořit revizní workflow, který zobrazí zpětnou vazbu okamžitě po přijetí dokumentu do vašeho pipeline. Exportujte výsledky do CSV nebo JSON a napojte je přímo na nástroje, které váš tým již používá.
Další kroky:
- Prozkoumejte GetAnnotations API reference pro kompletní signaturu metody a přetížení.
- Naučte se, jak extrahovat text z PDF dokumentů společně s anotacemi pro kompletní obsahový pipeline.
- Podívejte se na další ukázkové projekty na GitHubu pro scénáře dávkového zpracování (Examples Repo).