Search code examples
python-docx

How to change style of hyperlinks in existing document, especially font size and name


I would like to stick with python-docx library. But if there are other ways would love to hear them.

Currently i'm using this snippet for changing style in document, but links are no affected. Should I recreate them?

from docx import Document
from docx.shared import Pt

document = Document("existing file.docx")

for paragraph in document.paragraphs:
    # paragraph.style = document.styles['Normal']
    for run in paragraph.runs:
        run.font.name = 'Arial'
        run.font.size = Pt(10)

Snippet is from this answer.


Solution

  • from docx.oxml.shared import qn
    

    This function is copy-paste from here. Because paragraph.runs is not returning Run instances for hyperlinks childrens.

    def getParagraphRuns(paragraph):
        def _get(node, parent):
            for child in node:
                if child.tag == qn('w:r'):
                    yield Run(child, parent)
                if child.tag == qn('w:hyperlink'):
                    yield from _get(child, parent)
        return list(_get(paragraph._element, paragraph))
    

    If you want to get sequence of Run instances only for hyperlinks use this function instead.

    def getHyperlinksRuns(paragraph):
        def _get(node, parent):
            for child in node:
                if child.tag == qn('w:hyperlink'):
                    yield from returnRun(child, parent)
        def returnRun(node, parent):
            for child in node:
                if child.tag == qn('w:r'):
                    yield Run(child, parent)
        return list(_get(paragraph._element, paragraph))
    

    and voila

    for p in document.paragraphs:
        runs = getParagraphRuns(p) 
        # runs = getHyperlinksRuns(p)
        for run in runs:
            run.font.name = 'Arial'
            run.font.size = Pt(10)