DEV Community

Allen Yang
Allen Yang

Posted on

Adding and Managing Hyperlinks and Actions in PDF Using Python

Inserting and Managing Shapes in Excel Using Python

PDF hyperlinks and actions are essential mechanisms for enhancing document interactivity. Hyperlinks allow readers to navigate from a PDF to websites, files, or other pages within the document, while actions can trigger operations such as opening files, executing JavaScript, or playing sounds. When generating reports, electronic manuals, or interactive forms, manually adding links one by one is both time-consuming and error-prone. Using Python to batch-add and manage these links and actions programmatically significantly improves efficiency and ensures consistency. This article will introduce how to create various types of hyperlinks, set navigation actions, extract and update existing links, and configure document open actions in PDF documents using Python.

Why Manage Hyperlinks Programmatically

  • Batch creation: Automatically add table-of-content links and cross-references when generating multi-page reports
  • Rich types: Support web links, in-document navigation, file launching, and JavaScript actions
  • Precise control: Position link regions accurately using coordinates and dimensions, avoiding manual drag-and-drop imprecision
  • Automation integration: Embed link creation into document generation pipelines for one-pass generation with automatic linking

Environment Setup

This article uses Spire.PDF for Python, which provides a complete API for creating and managing PDF hyperlinks and actions.

pip install Spire.PDF
Enter fullscreen mode Exit fullscreen mode

Creating Web Hyperlinks

Web hyperlinks are the most common link type, allowing readers to click and navigate to external websites. Spire.PDF offers two approaches: PdfTextWebLink is convenient for quickly creating styled text links, while PdfUriAnnotation provides lower-level URI annotation control.

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

outputFile = "WebLink.pdf"

# Create a PDF document
doc = PdfDocument()
page = doc.Pages.Add()

# Method 1: Use PdfTextWebLink to create a text web link
font = PdfTrueTypeFont("Arial", 14.0, PdfFontStyle.Underline, True)
link = PdfTextWebLink()
link.Text = "Visit E-iceblue"
link.Url = "http://www.e-iceblue.com"
link.Font = font
link.Brush = PdfBrushes.get_CadetBlue()
link.DrawTextWebLink(page.Canvas, PointF(10.0, 50.0))

# Method 2: Use PdfUriAnnotation to create a URI annotation link
text = "Google"
font2 = PdfTrueTypeFont("Arial", 14.0, PdfFontStyle.Underline, True)
size = font2.MeasureString(text)
bounds = RectangleF(10.0, 100.0, size.Width, size.Height)

uriAnnotation = PdfUriAnnotation(bounds)
uriAnnotation.Uri = "http://www.google.com"
uriAnnotation.Border = PdfAnnotationBorder(0.0)

newPage = PdfNewPage(page.Ptr)
newPage.Annotations.Add(uriAnnotation)
page.Canvas.DrawString(text, font2, PdfBrushes.get_CadetBlue(), 10.0, 100.0)

# Email links are also supported
emailLink = PdfTextWebLink()
emailLink.Text = "Send an email"
emailLink.Url = "mailto:support@e-iceblue.com"
emailLink.Font = font
emailLink.Brush = PdfBrushes.get_CadetBlue()
emailLink.DrawTextWebLink(page.Canvas, PointF(10.0, 150.0))

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

PdfTextWebLink encapsulates both text rendering and link addition in one step, making it suitable for simple scenarios. PdfUriAnnotation requires manual calculation of the link region's RectangleF bounds, but allows further configuration of border, color, and other annotation properties.

Creating In-Document Links

In-document links allow readers to jump from one page to another within the same document, commonly used for tables of contents and cross-references. Creating an internal link requires a PdfDestination to specify the target page and position, then a PdfDocumentLinkAnnotation to create the link annotation.

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

outputFile = "DocumentLink.pdf"

doc = PdfDocument()
page1 = doc.Pages.Add()
page2 = doc.Pages.Add()

# Draw target content on the second page
page2.Canvas.DrawString("This is the target page!",
    PdfTrueTypeFont("Arial", 16.0, PdfFontStyle.Bold, True),
    PdfBrushes.get_Black(), 10.0, 50.0)

# Create a PdfDestination pointing to the second page
dest = PdfDestination(page2)
dest.Location = PointF(0.0, 50.0)
dest.Zoom = 0.5  # 50% zoom

# Create the in-document link
font = PdfTrueTypeFont("Arial", 12.0, PdfFontStyle.Regular, True)
label = "Click here to jump to page 2"
size = font.MeasureString(label)
bounds = RectangleF(10.0, 50.0, size.Width, size.Height)

annotation = PdfDocumentLinkAnnotation(bounds, dest)
annotation.Color = PdfRGBColor(Color.get_Blue())

page1.Canvas.DrawString(label, font, PdfBrushes.get_OrangeRed(), 10.0, 50.0)
newPage = PdfNewPage(page1.Ptr)
newPage.Annotations.Add(annotation)

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

The Location property of PdfDestination specifies the coordinate position on the target page, while Zoom controls the zoom level after navigation.

Creating File Links and Launch Actions

File links allow opening external files from within a PDF. PdfFileLinkAnnotation directly links to a file path, while PdfLaunchAction triggers file launching as an action and can also control whether the file opens in a new window.

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

outputFile = "FileLink.pdf"

doc = PdfDocument()
page = doc.Pages.Add()

# Create a launch action using PdfLaunchAction
launchAction = PdfLaunchAction("Sample.pdf")
# Set to open in a new window
launchAction.IsNewWindow = True

text = "Click to open Sample.pdf"
font = PdfTrueTypeFont("Arial", 13.0, PdfFontStyle.Regular, True)
rect = RectangleF(50.0, 50.0, 230.0, 20.0)
page.Canvas.DrawString(text, font, PdfBrushes.get_ForestGreen(), rect)

annotation = PdfActionAnnotation(rect, launchAction)
newPage = PdfNewPage(page.Ptr)
newPage.Annotations.Add(annotation)

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

PdfActionAnnotation associates an action with a rectangular region on the page. Clicking that region triggers the action. When IsNewWindow is set to True, the target file opens in a new window.

Using GoToAction for Page Navigation

PdfGoToAction is another way to implement page navigation. It works as an action rather than an annotation. Combined with PdfActionAnnotation, it can create button-style navigation regions, and it can also be set as an automatic behavior when the document opens.

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

outputFile = "GoToAction.pdf"

doc = PdfDocument()
page1 = doc.Pages.Add()
page2 = doc.Pages.Add()

page2.Canvas.DrawString("This is Page Two.",
    PdfFont(PdfFontFamily.Helvetica, 20.0),
    PdfSolidBrush(PdfRGBColor(Color.get_Black())), 10.0, 10.0)

# Create a go-to action targeting the second page
dest = PdfDestination(page2)
dest.Location = PointF(0.0, 5.0)
dest.Mode = PdfDestinationMode.Location
dest.Zoom = 1.0
gotoAction = PdfGoToAction(dest)

# Create a button-style navigation region
buttonFont = PdfTrueTypeFont("Arial", 10.0, PdfFontStyle.Bold, True)
buttonBounds = RectangleF(0.0, 100.0, 90.0, 20.0)
format = PdfStringFormat(PdfTextAlignment.Center, PdfVerticalAlignment.Middle)

page1.Canvas.DrawRectangle(PdfBrushes.get_DarkGray(), buttonBounds)
page1.Canvas.DrawString("Go to Page 2", buttonFont,
    PdfBrushes.get_CadetBlue(), buttonBounds, format)

annotation = PdfActionAnnotation(buttonBounds, gotoAction)
annotation.Border = PdfAnnotationBorder(0.75)
newPage = PdfNewPage(page1.Ptr)
newPage.Annotations.Add(annotation)

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

Extracting and Updating Existing Hyperlinks

For existing PDF documents, you can iterate through page annotations to extract link information or update link URLs:

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

inputFile = "Input.pdf"
outputFile = "UpdatedLinks.pdf"

doc = PdfDocument()
doc.LoadFromFile(inputFile)

# Iterate through annotations on each page
for i in range(doc.Pages.Count):
    page = doc.Pages[i]
    widgetCollection = page.AnnotationsWidget
    if widgetCollection.Count > 0:
        for j in range(widgetCollection.Count):
            annotation = widgetCollection.get_Item(j)
            # Check if it is a web link annotation
            if isinstance(annotation, PdfTextWebLinkAnnotationWidget):
                link = annotation
                print("URL: " + link.Url)
                print("Text: " + link.Text)
                # Update the link URL
                link.Url = "http://www.e-iceblue.com"

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

Use page.AnnotationsWidget to access the annotation collection, and isinstance to check the annotation type. PdfTextWebLinkAnnotationWidget provides Url and Text properties that can be directly read or modified.

Setting Document Open Actions

The AfterOpenAction property specifies an action to execute automatically when the document opens. Common use cases include navigating to a specific page, playing sound, and removing existing actions:

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

inputFile = "Input.pdf"
outputFile = "OpenAction.pdf"

doc = PdfDocument()
doc.LoadFromFile(inputFile)

# Set to jump to page 3 at 50% zoom when opened
dest = PdfDestination(2, PointF(0.0, 100.0), 0.5)
action = PdfGoToAction(dest)
doc.AfterOpenAction = action

doc.SaveToFile(outputFile)
doc.Close()

# To remove the open action, set AfterOpenAction to None
# doc.AfterOpenAction = None
Enter fullscreen mode Exit fullscreen mode

In addition to PdfGoToAction, you can also set PdfJavaScriptAction or PdfSoundAction as AfterOpenAction to execute scripts or play audio when the document opens.

Practical Tip: Auto-Generating a Linked Table of Contents

By combining PdfGoToAction with text rendering, you can automatically generate a table of contents page with page-navigation links for multi-page PDFs:

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

inputFile = "Input.pdf"
outputFile = "TOC.pdf"

doc = PdfDocument()
doc.LoadFromFile(inputFile)
pageCount = doc.Pages.Count

# Insert a TOC page at the beginning
tocPage = doc.Pages.Insert(0)
titleFont = PdfTrueTypeFont("Arial", 20.0, PdfFontStyle.Bold, True)
tocFont = PdfTrueTypeFont("Arial", 14.0, PdfFontStyle.Regular, True)

# Draw the title
tocPage.Canvas.DrawString("Table of Contents", titleFont,
    PdfBrushes.get_CornflowerBlue(), 0.0, 0.0)

# Create a TOC entry and navigation link for each page
y = 40.0
newPage = PdfNewPage(tocPage.Ptr)
for i in range(1, pageCount + 1):
    text = "Page {0}".format(i)
    size = tocFont.MeasureString(text)
    tocPage.Canvas.DrawString(text, tocFont, PdfBrushes.get_CadetBlue(), 0.0, y)

    # Create a navigation link to the target page
    dest = PdfDestination(doc.Pages[i], PointF(0.0, 0.0))
    gotoAction = PdfGoToAction(dest)
    bounds = RectangleF(0.0, y, tocPage.Canvas.ClientSize.Width, size.Height)
    action = PdfActionAnnotation(bounds, gotoAction)
    action.Border = PdfAnnotationBorder(0.0)
    newPage.Annotations.Add(action)
    y += size.Height + 10

doc.SaveToFile(outputFile)
doc.Close()
Enter fullscreen mode Exit fullscreen mode

This example inserts a blank page at the beginning as the table of contents, creates a text entry for each subsequent page, and overlays a transparent PdfActionAnnotation on each entry that navigates to the corresponding page when clicked.

Summary

This article covered the complete workflow for adding and managing hyperlinks and actions in PDF documents using Python, including web links, in-document links, file launch actions, page navigation actions, link extraction and updating, and document open action configuration.

Key takeaways:

  1. Use PdfTextWebLink for quick web link creation, and PdfUriAnnotation for finer URI annotation control
  2. PdfDocumentLinkAnnotation combined with PdfDestination enables in-document page navigation with configurable zoom levels
  3. PdfLaunchAction launches external files, with IsNewWindow controlling whether they open in a new window
  4. PdfGoToAction implements page navigation as an action, associable with page regions via PdfActionAnnotation
  5. Iterate page.AnnotationsWidget to extract and update existing links, and use AfterOpenAction to configure automatic behavior on document open

With these skills, you can add rich interactive navigation to PDF documents, auto-generate table-of-contents links, and integrate link management into your document processing pipelines.

Top comments (0)