Hur man arbetar med PDF-anteckningar i C++
Aspose.PDF FOSS för C++ representerar varje PDF-annotation som en subklass till den gemensamma basklassen Annotation, och exponerar annotationerna på en sida via AnnotationCollection som returneras av Page::Annotations(). Denna guide lägger till en enkel textanteckning-annotation och en stylad annotation på en sida med TextAnnotation, sparar dokumentet, öppnar sedan igen för att läsa tillbaka annotationerna och ta bort en. Biblioteket integreras i ett CMake-projekt som ett underkatalog-beroende — det finns inget installationssteg via paketregister.
Steg-för-steg-guide
Steg 1: Installera paketet
Lägg till biblioteket som en CMake-underkatalog och länka mot det statiska biblioteksmål:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Verifiera att verktygskedjan och länkningssteget löser sig korrekt med ett minimalt program:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}En lyckad byggnad som skriver ut pages: 0 bekräftar att biblioteket är länkat.
Steg 2: Importera nödvändiga klasser
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/rectangle.hpp>
#include <aspose/pdf/color.hpp>
#include <aspose/pdf/annotations/annotation.hpp>
#include <aspose/pdf/annotations/annotation_collection.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
#include <aspose/pdf/annotations/annotation_flags.hpp>
#include <aspose/pdf/annotations/border.hpp>
#include <aspose/pdf/annotations/border_style.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;Steg 3: Skapa ett dokument och lägg till en sida
Skapa ett nytt dokument och lägg till en sida i det. PageCollection::Add() returnerar den nyss tillagda Page:
Document doc;
Page page = doc.Pages().Add();Steg 4: Lägg till en textanteckning på sidan
TextAnnotation renderas som en post-it-stil kommentar. Konstruera den från den ägande Document, sätt dess position med Rect() och dess meddelande med Contents(), lägg sedan till den i sidans AnnotationCollection:
TextAnnotation note{doc};
note.Rect(Rectangle(100.0, 700.0, 200.0, 720.0, false));
note.Contents("Reviewed and approved.");
page.Annotations().Add(note);Steg 5: Formatera en andra anteckning med färg, en ram och flaggor
Annotation exponerar också Color(), Border() och Flags(). Flags() tar ett AnnotationFlags bitfält — kombinera värden med bitvis OR för att sätta fler än en flagga åt gången:
TextAnnotation flagged{doc};
flagged.Rect(Rectangle(100.0, 600.0, 300.0, 650.0, false));
flagged.Contents("Needs follow-up");
flagged.Color(Color::FromRgb(220, 20, 20));
flagged.Flags(AnnotationFlags::Print | AnnotationFlags::ReadOnly);
flagged.Border().Width(2);
flagged.Border().Style(BorderStyle::Dashed);
page.Annotations().Add(flagged);Steg 6: Spara dokumentet
Ingenting skrivs till disk förrän Save() körs:
doc.Save("annotated.pdf");Steg 7: Öppna PDF-filen igen och läs dess anteckningar
Öppna den sparade filen igen och läs tillbaka dess första sidas AnnotationCollection. AnnotationCollection är 0-baserad och Count() rapporterar hur många anteckningar sidan innehåller:
Document reopened("annotated.pdf");
auto& annots = reopened.Pages()[1].Annotations();
std::cout << "Annotation count: " << annots.Count() << "\n";
for (int i = 0; i < annots.Count(); ++i) {
const auto& a = annots[i];
if (a.AnnotationType() == AnnotationType::Text) {
std::cout << "Text annotation: " << a.Contents() << "\n";
}
}Steg 8: Ta bort en anteckning och spara igen
AnnotationCollection::Delete(index) tar bort en anteckning efter dess 0-baserade position. Ta bort den första anteckningen och spara resultatet till en ny fil:
annots.Delete(0);
reopened.Save("annotated-cleaned.pdf");Vanliga problem och lösningar
Inget ändras i den sparade PDF-filen efter att ha anropat Annotations().Add()
Två saker går ofta fel här. Först är PageCollection 1-baserad (doc.Pages()[1] är den första sidan) medan AnnotationCollection är 0-baserad (annots[0] är den första annoteringen) — att blanda ihop de två indexeringsscheman leder till att man opererar på fel objekt. För det andra, bekräfta att Document::Save() faktiskt körs efter att annoteringen har lagts till; inget skrivs till disk förrän dess.
AnnotationCollection indexering eller Delete(index) throws std::out_of_range
Giltiga index sträcker sig från 0 till Count() - 1. Att skicka ett negativt index eller ett index som är lika med eller större än Count() kastar std::out_of_range av design. Anropa Count() först för att begränsa någon loop eller uppslagning.
Remove() returns false andra gången jag anropar den på samma annotation
Detta är inget fel. Remove() rapporterar huruvida annoteringen hittades och togs bort som en bool; att anropa den igen på en annotering som redan är borta är en ingen-åtgärd som returnerar false. Kontrollera returvärdet istället för att anta att Remove() alltid lyckas.
Ställa in en ny AnnotationFlags värde rensar flaggor jag redan har satt
Flags(value) ersätter hela flaggsättet — det slår inte ihop med det tidigare värdet. För att lägga till eller rensa en enskild flagga, läs först de aktuella flaggorna och kombinera dem med bitvisa operatorer, till exempel a.Flags(a.Flags() | AnnotationFlags::Print) för att lägga till en flagga, eller a.Flags(a.Flags() & ~AnnotationFlags::Print) för att rensa en flagga medan resten lämnas orörda.
Vanliga frågor
Vad är förhållandet mellan Annotation, TextAnnotation och de andra annoteringstyperna?
Annotation är den gemensamma basklassen. TextAnnotation och de andra konkreta annoteringstyperna specialiserar den för en PDF-annoteringstyp, samtidigt som de delar basklassens Rect(), Contents(), Color(), Flags() och Border() åtkomstmetoder.
Är annoteringar begränsade till hela dokumentet eller till en enskild sida?
Varje sida har sin egen AnnotationCollection, som returneras av sidans Annotations()-metod. Annoteringar är alltid begränsade till den sida de lades till på, inte till hela dokumentet.
Hur räknar jag hur många annoteringar som finns på en sida?
Anropa Count() på AnnotationCollection som returneras av Page::Annotations().
Kan en annotering vara både utskrivbar och skrivskyddad samtidigt?
Ja. AnnotationFlags är ett bitfält, så kombinera värden med bitvis OR, till exempel AnnotationFlags::Print | AnnotationFlags::ReadOnly.
Tar bort en annotation från AnnotationCollection den också från PDF-filen på disken?
Endast efter att Document::Save() körs. Delete(), Remove() och Clear() ändrar bara samlingen i minnet — PDF-filen på disken förblir oförändrad tills dokumentet sparas.