8 Ways to Annotate PDF Documents in Python (A Comprehensive Guide)

Alexander Stock
9 min readJun 7, 2024

--

Add annotations to PDF.

Annotations in PDF are a valuable feature that allows users to add comments, notes, highlights, and other types of markups to a PDF document. These annotations can enhance collaboration, communication, and understanding when reviewing or editing a PDF file.

In this post, I’ll walk you through the process of adding a variety types of annotations to a PDF document by using Python and the Spire.PDF for Python library.

Python Library for Annotating PDF Documents

Spire.PDF is a feature-rich Python library that allows developers to seamlessly work with PDF documents. A standout capability of Spire.PDF is its support for adding diverse annotations, including text notes, highlights, and stamps, to PDF files.

You can install the library from PyPI using the following pip command.

pip install Spire.PDF 

Annotation Types in PDF

PDF documents support a wide variety of annotation types that allow users to add comments, markups, interactive elements, and supplementary content to the document. Some of the most common annotation types are listed below.

Annotation types in PDF.
Figure 1. Annotation types in PDF.

General Steps to Add Annotations to PDF Using Spire.PDF

  • Step 1. Imports the necessary modules from the Spire.PDF library.
  • Step 2. Create a PdfDocument object to represent the PDF document.
  • Step 3. Load a PDF file from the specified location.
  • Step 4. Get a page from the document.
  • Step 5. Create a PdfTextFinder object to find a specific piece of text within the page.
  • Step 6. Get the bounds information of the desired text.
  • Step 7. Create an annotation of a certain type, and set its attributes.
  • Step 8. Add the annotation to the collection of annotations on the page.
  • Step 9. Save the modified document to a different PDF file.

Add a Markup Annotation to PDF in Python

This code example demonstrates how to use the Spire.PDF library to locate specific text within a PDF document and add text markup annotations to that text, saving the modified document to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("Before you use or submit any information through or in connection with the Services, " +
"please carefully review this Privacy Policy.");

# Get the first instance
textFragment = fragments[0]

# Specify annotation text
text = "This is a markup annotation."

# Iterate through the text bounds
for i in range(len(textFragment.Bounds)):

# Get a specific bound
rect = textFragment.Bounds[i]

# Create a text markup annotation
annotation = PdfTextMarkupAnnotation("Administrator", text, rect)

# Set the markup color
annotation.TextMarkupColor = PdfRGBColor(Color.get_Green())

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(annotation)

# Save result to file
doc.SaveToFile("output/Markups.pdf")

# Dispose resources
doc.Dispose()
Add a markup annotation to PDF.
Figure 2. Add a markup annotation to PDF.

Add a Free Text Annotation to PDF in Python

This code example showcases the process of utilizing the Spire.PDF library to search for targeted text in a PDF document, create a free text annotation, and then save the annotated PDF to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
rect = textFragment.Bounds[0]

# Get the x and y coordinates to add annotation
x = rect.Right
y = rect.Bottom

# Create a free text annotation
rectangle = RectangleF(x, y, 130.0, 20.0)
textAnnotation = PdfFreeTextAnnotation(rectangle)

# Set the content of the annotation
textAnnotation.Text = "This is a free text annotation."

# Set other properties of annotation
font = PdfFont(PdfFontFamily.TimesRoman, 10.0, PdfFontStyle.Bold)
border = PdfAnnotationBorder(1.0)
textAnnotation.Font = font
textAnnotation.Border = border
textAnnotation.BorderColor = PdfRGBColor(Color.get_Purple())
textAnnotation.Color = PdfRGBColor(Color.get_Green())
textAnnotation.Opacity = 1.0

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(textAnnotation)

# Save result to file
doc.SaveToFile("output/FreeTextAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a free text annotation to PDF.
Figure 3. Add a free text annotation to PDF.

Add a Popup Annotation to PDF in Python

This code example demonstrates how to identify targeted text within a PDF document, add a popup annotation to the relevant area, and save the annotated PDF to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
bound = textFragment.Bounds[0]

# Get the x and y coordinates to add annotation
x = bound.Right
y = bound.Bottom

# Create a free text annotation
rectangle = RectangleF(x, y, 30.0, 30.0)
popupAnnotation = PdfPopupAnnotation(rectangle)

# Set the content of the annotation
popupAnnotation.Text = "This is a popup annotation."

# Set the icon and color of the annotation
popupAnnotation.Icon = PdfPopupIcon.Comment
popupAnnotation.Color = PdfRGBColor(Color.get_Red())

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(popupAnnotation)

# Save result to file
doc.SaveToFile("output/PopupAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a popup annotation to PDF.
Figure 4. Add a popup annotation to PDF.

Add a Stamp Annotation to PDF in Python

This code example showcases how to create a rubber stamp annotation with the image as its appearance, add the annotation to the PDF page, and save the modified document to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF document
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Load an image file
image = PdfImage.FromFile("C:\\Users\\Administrator\\Desktop\\approved.png")

# Get the width and height of the image
width = (float)(image.Width)
height = (float)(image.Height)

# Create a PdfTemplate object based on the size of the image
template = PdfTemplate(width, height, True)

# Draw image on the template
template.Graphics.DrawImage(image, 0.0, 0.0, width, height)

# Create a rubber stamp annotation, specifying its location and position
rect = RectangleF((float) (page.ActualSize.Width - width - 50), (float) (page.ActualSize.Height - height - 40), width, height)
stamp = PdfRubberStampAnnotation(rect)

# Create a PdfAppearance object
pdfAppearance = PdfAppearance(stamp)

# Set the template as the normal state of the appearance
pdfAppearance.Normal = template

# Apply the appearance to the stamp
stamp.Appearance = pdfAppearance

# Add the stamp annotation to PDF
page.AnnotationsWidget.Add(stamp)

# Save the file
doc.SaveToFile("output/StampAnnotation.pdf")

# Dispose resources
doc.Close()
Add a stamp annotation to PDF.
Figure 5. Add a stamp annotation to PDF.

Add a Shape Annotation to PDF in Python

This example demonstrates how to locate specific text within a PDF document, retrieve the bounding box coordinates of the text, and add a shape annotation to the page based on those coordinates.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
bound = textFragment.Bounds[0]

# Get the coordinates to add annotation
left = bound.Left
top = bound.Top
right = bound.Right
bottom = bound.Bottom

# Create a shape annotation
polyLineAnnotation = PdfPolyLineAnnotation(page, [PointF(left, top), PointF(right, top), PointF(right - 5, bottom), PointF(left - 5, bottom), PointF(left, top)])

# Set the annotation text
polyLineAnnotation.Text = "This is a shape annotation."

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(polyLineAnnotation)

# Save result to file
doc.SaveToFile("output/ShapeAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a shape annotation to PDF.
Figure 6. Add a shape annotation to PDF.

Add a Web Link Annotation to PDF in Python

This code example illustrates the process of utilizing the Spire.PDF library to search for targeted text in a PDF document, create a web link annotation, and then save the annotated PDF to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
bound = textFragment.Bounds[0]

# Create a Url annotation
urlAnnotation = PdfUriAnnotation(bound, "https://www.medium.com/")

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(urlAnnotation)

# Save result to file
doc.SaveToFile("output/WebLinkAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a web link annotation to PDF.
Figure 7. Add a web link annotation to PDF.

Add a File Link Annotation to PDF in Python

This code example demonstrates how to search for targeted text in a PDF document, create a file link annotation, and then save the annotated PDF to a new file.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
bound = textFragment.Bounds[0]

# Create a file link annotation
fileLinkAnnotation = PdfFileLinkAnnotation(bound, "C:\\Users\\Administrator\\Desktop\\Report.docx")

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(fileLinkAnnotation)

# Save result to file
doc.SaveToFile("output/FileLinkAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a file link annotation to PDF.
Figure 8. Add a file link annotation to PDF.

Add a Document Link Annotation to PDF in Python

This code example searches for a specific text on a PDF page and adds a document link annotation to the text found, linking it to another page in the same PDF document.

from spire.pdf.common import *
from spire.pdf import *

# Create a PdfDocument object
doc = PdfDocument()

# Load a PDF file
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\sample.pdf")

# Get a specific page
page = doc.Pages[0]

# Create a PdfTextFinder object based on the page
finder = PdfTextFinder(page)

# Set the find options
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase

# Find the instances of the specified text
fragments = finder.Find("reasonable expectations");

# Get the first instance
textFragment = fragments[0]

# Get the text bound
bound = textFragment.Bounds[0]

# Create a document link annotation
documentLinkAnnotation = PdfDocumentLinkAnnotation(bound)

# Set the destination of the annotation
documentLinkAnnotation.Destination = PdfDestination(doc.Pages[1]);

# Add the annotation to the collection of the annotations
page.AnnotationsWidget.Add(documentLinkAnnotation)

# Save result to file
doc.SaveToFile("output/DocumentLinkAnnotation.pdf")

# Dispose resources
doc.Dispose()
Add a document link annotation to PDF.
Figure 9. Add a document link annotation to PDF.

Conclusion

In this blog post, we’ve explored the process of adding a variety of annotations to PDF documents using Python and the Spire.PDF library. From adding markup, free text, popup annotations, stamps, shapes, and different types of links, the examples covered provide a comprehensive overview of the PDF annotation capabilities available in this library.

By leveraging these techniques, developers can create more interactive and engaging PDF experiences for end-users.

See Also

--

--

Alexander Stock

I'm Alexander Stock, a software development consultant and blogger with 10+ years' experience. Specializing in office document tools and knowledge introduction.