question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

feature: Paragraph.add_hyperlink()

See original GitHub issue

Protocol might be something like this:

>>> hyperlink = paragraph.add_hyperlink(text='foobar', url='http://github.com')
>>> hyperlink
<docx.text.Hyperlink instance at 0xdeadbeef1>
>>> hyperlink.url
'http://github.com'
>>> hyperlink.text
'foobar'

XML specimen:

<w:p>
  <w:r>
    <w:t xml:space="preserve">This sentence has a </w:t>
  </w:r>
  <w:hyperlink r:id="rId5" w:history="1">
    <w:r>
      <w:rPr>
        <w:rStyle w:val="Hyperlink"/>
      </w:rPr>
      <w:t>hyperlink</w:t>
    </w:r>
  </w:hyperlink>
  <w:r>
    <w:t xml:space="preserve"> in it.</w:t>
  </w:r>
</w:p>

Issue Analytics

  • State:open
  • Created 9 years ago
  • Reactions:5
  • Comments:51 (6 by maintainers)

github_iconTop GitHub Comments

20reactions
johanvandegriffcommented, Nov 17, 2016

@posterberg I don’t know how to make a workaround that returns a run, but I have improved the current one to take the color and underline as arguments.

Here are the steps I took to change the text color, in case you need to add other properties:

  • Open the generated document in MS Word or LibreOffice and add a property by hand (in this case, change the text color).
  • Save the document
  • Unzip the .docx file (.docx files are normal zip archives).
  • Go into the word/ folder in the unzipped archive and open document.xml
  • It’s a bit of a mess, so search for the link text (in this case “Google”).
  • Look for the element that causes the property to change. For color it was <w:color w:val="FF8822"/> inside the <w:rPr> element. (Side note: rPr stands for “run Properties”)
  • Add an argument to the add_hyperlink function
  • Add a block of code that adds the property to rPr.
    # Add color if it is given
    if not color is None:
      c = docx.oxml.shared.OxmlElement('w:color')
      c.set(docx.oxml.shared.qn('w:val'), color)
      rPr.append(c)
  • Last step: post your solution so other people can benefit from it.

Here is the updated workaround with control of color and underlining:

import docx

def add_hyperlink(paragraph, url, text, color, underline):
    """
    A function that places a hyperlink within a paragraph object.

    :param paragraph: The paragraph we are adding the hyperlink to.
    :param url: A string containing the required url
    :param text: The text displayed for the url
    :return: The hyperlink object
    """

    # This gets access to the document.xml.rels file and gets a new relation id value
    part = paragraph.part
    r_id = part.relate_to(url, docx.opc.constants.RELATIONSHIP_TYPE.HYPERLINK, is_external=True)

    # Create the w:hyperlink tag and add needed values
    hyperlink = docx.oxml.shared.OxmlElement('w:hyperlink')
    hyperlink.set(docx.oxml.shared.qn('r:id'), r_id, )

    # Create a w:r element
    new_run = docx.oxml.shared.OxmlElement('w:r')

    # Create a new w:rPr element
    rPr = docx.oxml.shared.OxmlElement('w:rPr')

    # Add color if it is given
    if not color is None:
      c = docx.oxml.shared.OxmlElement('w:color')
      c.set(docx.oxml.shared.qn('w:val'), color)
      rPr.append(c)

    # Remove underlining if it is requested
    if not underline:
      u = docx.oxml.shared.OxmlElement('w:u')
      u.set(docx.oxml.shared.qn('w:val'), 'none')
      rPr.append(u)

    # Join all the xml elements together add add the required text to the w:r element
    new_run.append(rPr)
    new_run.text = text
    hyperlink.append(new_run)

    paragraph._p.append(hyperlink)

    return hyperlink



document = docx.Document()
p = document.add_paragraph()

#add a hyperlink with the normal formatting (blue underline)
hyperlink = add_hyperlink(p, 'http://www.google.com', 'Google', None, True)

#add a hyperlink with a custom color and no underline
hyperlink = add_hyperlink(p, 'http://www.google.com', 'Google', 'FF8822', False)

document.save('demo.docx')

This function is the hyperlink equivalent of duct tape: It get the job done, but becomes harder to use when the complexity of the task increases.

11reactions
johanvandegriffcommented, Sep 4, 2016

The workaround didn’t work for me. I had to modify it to insert the hyperlink directly into the paragraph:

def add_hyperlink(paragraph, url, text):
    """
    A function that places a hyperlink within a paragraph object.

    :param paragraph: The paragraph we are adding the hyperlink to.
    :param url: A string containing the required url
    :param text: The text displayed for the url
    :return: The hyperlink object
    """

    # This gets access to the document.xml.rels file and gets a new relation id value
    part = paragraph.part
    r_id = part.relate_to(url, docx.opc.constants.RELATIONSHIP_TYPE.HYPERLINK, is_external=True)

    # Create the w:hyperlink tag and add needed values
    hyperlink = docx.oxml.shared.OxmlElement('w:hyperlink')
    hyperlink.set(docx.oxml.shared.qn('r:id'), r_id, )

    # Create a w:r element
    new_run = docx.oxml.shared.OxmlElement('w:r')

    # Create a new w:rPr element
    rPr = docx.oxml.shared.OxmlElement('w:rPr')

    # Join all the xml elements together add add the required text to the w:r element
    new_run.append(rPr)
    new_run.text = text
    hyperlink.append(new_run)

    paragraph._p.append(hyperlink)

    return hyperlink



document = docx.Document()
p = document.add_paragraph()
add_hyperlink(p, 'http://www.google.com', 'Google')
document.save('demo.docx')
Read more comments on GitHub >

github_iconTop Results From Across the Web

Hyperlink | Documents for Word, .NET Edition
Load("AddHyperlink.docx"); //Modify the hyperlink code Hyperlink link1 = doc.Body.Sections.First.GetRange().Paragraphs.First.GetRange().Hyperlinks.
Read more >
MigraDoc Sample: Hello MigraDoc
This sample shows various features of MigraDoc including table of contents, ... all styles and paragraphs that do not redefine the font.
Read more >
Adding links to pdf by using MigraDoc
I tried to use AddHyperlink() for adding link, and it was the first step for this. The code below shows correct using: var...
Read more >
Working with Actions in PDF
Add Hyperlink in a PDF File ... It also offers the feature to add links to PDF pages and a link can either...
Read more >
Add hyperlinks to a location within the same document
Mark the hyperlink destination with a bookmark or a heading style. Insert a bookmark. Select text or an item, or click where you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found