How to Remove Hyperlinks in Word with Python Like a Pro

Casie LiuCasie Liu
6 min read

Hyperlinks can enhance a Word document by adding interactivity and linking to external resources. However, broken links or outdated file paths can disrupt the reading experience and clutter your content. In such cases, removing unnecessary hyperlinks is a great way to clean up the document. This guide will show you how to remove hyperlinks in Word using Python — whether you want to delete a specific hyperlink or remove all of them in bulk — to help you manage documents efficiently and automatically.

In Word documents, some hyperlinks may become unresponsive or point to incorrect locations, disrupting the reading experience. If you only need to remove a specific link in the Word document, Python makes it easy by allowing you to loop through the hyperlinks and remove the one by its index. With the help of free Spire.Doc for Python, a simple yet powerful library, this process becomes even more efficient. Let’s walk through the quick steps and code example below.

Steps to remove a hyperlink in Word documents:

  • Create an object of the Document class.

  • Load a Word document from files using the Document.LoadFromFile() method.

  • Find all hyperlinks in the document through the customized method FindAllHyperlinks().

  • Loop through all hyperlinks in the Word document and delete a hyperlink with the method FlattenHyperlinks().

  • Save the updated Word document using the Document.SaveToFile() method.

The code example here shows how to remove the second hyperlink in a Word document:

from spire.doc import *
from spire.doc.common import *

# Find all the hyperlinks in a document
def FindAllHyperlinks(document):
    hyperlinks = []
    for i in range(document.Sections.Count):
        section = document.Sections.get_Item(i)
        for j in range(section.Body.ChildObjects.Count):
            sec = section.Body.ChildObjects.get_Item(j)
            if sec.DocumentObjectType == DocumentObjectType.Paragraph:
                for k in range((sec if isinstance(sec, Paragraph) else None).ChildObjects.Count):
                    para = (sec if isinstance(sec, Paragraph)
                            else None).ChildObjects.get_Item(k)
                    if para.DocumentObjectType == DocumentObjectType.Field:
                        field = para if isinstance(para, Field) else None
                        if field.Type == FieldType.FieldHyperlink:
                            hyperlinks.append(field)
    return hyperlinks

# Flatten the hyperlink fields
def FlattenHyperlinks(field):
    ownerParaIndex = field.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.OwnerParagraph)
    fieldIndex = field.OwnerParagraph.ChildObjects.IndexOf(field)
    sepOwnerPara = field.Separator.OwnerParagraph
    sepOwnerParaIndex = field.Separator.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.Separator.OwnerParagraph)
    sepIndex = field.Separator.OwnerParagraph.ChildObjects.IndexOf(
        field.Separator)
    endIndex = field.End.OwnerParagraph.ChildObjects.IndexOf(field.End)
    endOwnerParaIndex = field.End.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.End.OwnerParagraph)

    FormatFieldResultText(field.Separator.OwnerParagraph.OwnerTextBody,
                           sepOwnerParaIndex, endOwnerParaIndex, sepIndex, endIndex)

    field.End.OwnerParagraph.ChildObjects.RemoveAt(endIndex)

    for i in range(sepOwnerParaIndex, ownerParaIndex - 1, -1):
        if i == sepOwnerParaIndex and i == ownerParaIndex:
            for j in range(sepIndex, fieldIndex - 1, -1):
                field.OwnerParagraph.ChildObjects.RemoveAt(j)

        elif i == ownerParaIndex:
            for j in range(field.OwnerParagraph.ChildObjects.Count - 1, fieldIndex - 1, -1):
                field.OwnerParagraph.ChildObjects.RemoveAt(j)

        elif i == sepOwnerParaIndex:
            for j in range(sepIndex, -1, -1):
                sepOwnerPara.ChildObjects.RemoveAt(j)
        else:
            field.OwnerParagraph.OwnerTextBody.ChildObjects.RemoveAt(i)

# Convert fields to text range and clear the text formatting
def FormatFieldResultText(ownerBody, sepOwnerParaIndex, endOwnerParaIndex, sepIndex, endIndex):
    for i in range(sepOwnerParaIndex, endOwnerParaIndex + 1):
        para = ownerBody.ChildObjects[i] if isinstance(
            ownerBody.ChildObjects[i], Paragraph) else None
        if i == sepOwnerParaIndex and i == endOwnerParaIndex:
            for j in range(sepIndex + 1, endIndex):
               if isinstance(para.ChildObjects[j], TextRange):
                 FormatText(para.ChildObjects[j])

        elif i == sepOwnerParaIndex:
            for j in range(sepIndex + 1, para.ChildObjects.Count):
                if isinstance(para.ChildObjects[j], TextRange):
                  FormatText(para.ChildObjects[j])
        elif i == endOwnerParaIndex:
            for j in range(0, endIndex):
               if isinstance(para.ChildObjects[j], TextRange):
                 FormatText(para.ChildObjects[j])
        else:
            for j, unusedItem in enumerate(para.ChildObjects):
                if isinstance(para.ChildObjects[j], TextRange):
                  FormatText(para.ChildObjects[j])

# Format text
def FormatText(tr):
    tr.CharacterFormat.TextColor = Color.get_Black()
    tr.CharacterFormat.UnderlineStyle = UnderlineStyle.none

# Create a Document object
doc = Document()

# Load a Word file
doc.LoadFromFile("/sample.docx")

# Get all hyperlinks
hyperlinks = FindAllHyperlinks(doc)

# Flatten the second hyperlink
target_index = 1
if 0 <= target_index < len(hyperlinks):
    FlattenHyperlinks(hyperlinks[target_index])

# Save the document as a new file
doc.SaveToFile("/RemoveaHyperlink.docx", FileFormat.Docx)
doc.Close()

How to Remove a Hyperlink in Word Files with Python

When a Word document contains a large number of outdated or broken links, manually deleting them one by one can be time-consuming. In such cases, it's more efficient to remove all hyperlinks in Word files in bulk. The process is similar to deleting individual hyperlinks, except that it requires reverse iteration to avoid index errors. In this section, you’ll learn how to automate this task with Python and simplify link cleanup across entire documents.

Steps to remove all hyperlinks in Word documents:

  • Create a Document instance and read a Word document from files

  • Find all hyperlinks in the document with the FindAllHyperlinks() method.

  • Loop through all hyperlinks and delete all hyperlinks using the FlattenHyperlinks() method.

  • Save the modified Word document.

The Python example below shows how to remove all hyperlinks in a Word file:

from spire.doc import *
from spire.doc.common import *

# Find all the hyperlinks in a document
def FindAllHyperlinks(document):
    hyperlinks = []
    for i in range(document.Sections.Count):
        section = document.Sections.get_Item(i)
        for j in range(section.Body.ChildObjects.Count):
            sec = section.Body.ChildObjects.get_Item(j)
            if sec.DocumentObjectType == DocumentObjectType.Paragraph:
                for k in range((sec if isinstance(sec, Paragraph) else None).ChildObjects.Count):
                    para = (sec if isinstance(sec, Paragraph)
                            else None).ChildObjects.get_Item(k)
                    if para.DocumentObjectType == DocumentObjectType.Field:
                        field = para if isinstance(para, Field) else None
                        if field.Type == FieldType.FieldHyperlink:
                            hyperlinks.append(field)
    return hyperlinks

# Flatten the hyperlink fields
def FlattenHyperlinks(field):
    ownerParaIndex = field.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.OwnerParagraph)
    fieldIndex = field.OwnerParagraph.ChildObjects.IndexOf(field)
    sepOwnerPara = field.Separator.OwnerParagraph
    sepOwnerParaIndex = field.Separator.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.Separator.OwnerParagraph)
    sepIndex = field.Separator.OwnerParagraph.ChildObjects.IndexOf(
        field.Separator)
    endIndex = field.End.OwnerParagraph.ChildObjects.IndexOf(field.End)
    endOwnerParaIndex = field.End.OwnerParagraph.OwnerTextBody.ChildObjects.IndexOf(
        field.End.OwnerParagraph)

    FormatFieldResultText(field.Separator.OwnerParagraph.OwnerTextBody,
                           sepOwnerParaIndex, endOwnerParaIndex, sepIndex, endIndex)

    field.End.OwnerParagraph.ChildObjects.RemoveAt(endIndex)

    for i in range(sepOwnerParaIndex, ownerParaIndex - 1, -1):
        if i == sepOwnerParaIndex and i == ownerParaIndex:
            for j in range(sepIndex, fieldIndex - 1, -1):
                field.OwnerParagraph.ChildObjects.RemoveAt(j)

        elif i == ownerParaIndex:
            for j in range(field.OwnerParagraph.ChildObjects.Count - 1, fieldIndex - 1, -1):
                field.OwnerParagraph.ChildObjects.RemoveAt(j)

        elif i == sepOwnerParaIndex:
            for j in range(sepIndex, -1, -1):
                sepOwnerPara.ChildObjects.RemoveAt(j)
        else:
            field.OwnerParagraph.OwnerTextBody.ChildObjects.RemoveAt(i)

# Convert fields to text range and clear the text formatting
def FormatFieldResultText(ownerBody, sepOwnerParaIndex, endOwnerParaIndex, sepIndex, endIndex):
    for i in range(sepOwnerParaIndex, endOwnerParaIndex + 1):
        para = ownerBody.ChildObjects[i] if isinstance(
            ownerBody.ChildObjects[i], Paragraph) else None
        if i == sepOwnerParaIndex and i == endOwnerParaIndex:
            for j in range(sepIndex + 1, endIndex):
               if isinstance(para.ChildObjects[j], TextRange):
                 FormatText(para.ChildObjects[j])

        elif i == sepOwnerParaIndex:
            for j in range(sepIndex + 1, para.ChildObjects.Count):
                if isinstance(para.ChildObjects[j], TextRange):
                  FormatText(para.ChildObjects[j])
        elif i == endOwnerParaIndex:
            for j in range(0, endIndex):
               if isinstance(para.ChildObjects[j], TextRange):
                 FormatText(para.ChildObjects[j])
        else:
            for j, unusedItem in enumerate(para.ChildObjects):
                if isinstance(para.ChildObjects[j], TextRange):
                  FormatText(para.ChildObjects[j])

# Format text
def FormatText(tr):
    tr.CharacterFormat.TextColor = Color.get_Black()
    tr.CharacterFormat.UnderlineStyle = UnderlineStyle.none

# Create a Document object
doc = Document()

# Load a Word file
doc.LoadFromFile("/sample.docx")

# Get all hyperlinks
hyperlinks = FindAllHyperlinks(doc)

# Flatten all hyperlinks
for i in range(len(hyperlinks) - 1, -1, -1):
    FlattenHyperlinks(hyperlinks[i])

# Save to a different file
doc.SaveToFile("/RemoveAllHyperlinks.docx", FileFormat.Docx)
doc.Close()

How to Remove All Hyperlinks in Word Documents Using Python

The Bottom Line

By using Python and the Spire.Doc library, you can efficiently remove individual or all hyperlinks from Word documents. Whether you're cleaning up a few outdated links or streamlining an entire document, automating the process helps maintain a clean, professional result with minimal effort.

Q1: How do I unclick a hyperlink in Word?

Right-click the hyperlink, then select "Remove Hyperlink" from the context menu.

Q2: How do I remove a hyperlink in Docs?

Right-click the hyperlink and select "Remove Hyperlink".

If you're using Python, you can also use FlattenHyperlinks() from Spire.Doc to remove all hyperlinks programmatically.

(In Google Docs, simply right-click the hyperlink and choose "Remove link.")。

Q3: How do I edit hyperlinks in Word?

Right-click the hyperlink, then choose "Edit Hyperlink" to modify the address or display text.

Q4: How do I remove a hyperlink on Word on my Mac?

Control-click (or right-click) the hyperlink, then choose "Remove Hyperlink" from the menu.

Alternatively, you can press Command + 6 after selecting the hyperlink to remove it quickly.

0
Subscribe to my newsletter

Read articles from Casie Liu directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Casie Liu
Casie Liu