Search code examples
pythonpython-docx

How to place a link in a table without next line at the beginning?


I would like to create a table with links to pictures. I have a code presented below, which almost does the task. The problem is that it places a new line before each link text. How to avoid placing a new line before the link text in a table cell? Is it possible to place a link without making a new paragraph in a cell?

from docx import Document
from docx.oxml.shared import OxmlElement, qn
import docx
from lxml.etree import SubElement

def add_link(paragraph, link_to, text, tool_tip=None):
    # create hyperlink node
    hyperlink = docx.oxml.shared.OxmlElement('w:hyperlink')

    # set attribute for link to bookmark
    hyperlink.set(docx.oxml.shared.qn('w:anchor'), link_to,)

    if tool_tip is not None:
    # set attribute for link to bookmark
        hyperlink.set(docx.oxml.shared.qn('w:tooltip'), tool_tip,)

    new_run = docx.oxml.shared.OxmlElement('w:r')
    rPr = docx.oxml.shared.OxmlElement('w:rPr')
    c = docx.oxml.shared.OxmlElement('w:color')
    c.set(docx.oxml.shared.qn('w:val'), '2A6099')
    rPr.append(c)
    u = docx.oxml.shared.OxmlElement('w:u')
    u.set(docx.oxml.shared.qn('w:val'), 'single')
    rPr.append(u)
    new_run.append(rPr)
    new_run.text = text
    hyperlink.append(new_run)
    paragraph._p.append(hyperlink)  # this to add the link in the w:p

def add_bookmark(paragraph, bookmark_text, bookmark_name):
    run = paragraph.add_run()
    r = run._r
    
    SubElement(r, qn('w:bookmarkStart'), {
        qn('w:id'): '0',
        qn('w:name'): bookmark_name,
    })

    SubElement(r, qn('w:r'), {
        qn('w:t'): bookmark_text,
    })

    SubElement(r, qn('w:bookmarkEnd'), {
        qn('w:id'): '0',
        qn('w:name'): bookmark_name,
    })

document = Document()
c = document.add_paragraph('Figure ', style='Caption')
add_bookmark(paragraph=c, bookmark_text="", bookmark_name=f"test")

document.add_page_break()

table = document.add_table(rows=1, cols=8)
table.style = 'Table Grid'

hdr_cells = table.rows[0].cells
e = hdr_cells[0].add_paragraph()
add_link(paragraph = e, link_to=f"test", text="test", tool_tip="PSD")

e = hdr_cells[1].add_paragraph()
add_link(paragraph = e, link_to=f"test", text="test", tool_tip="PSD")
document.save('link_in_table.docx')

Solution

  • The documentation for the table cell says:

    By default, a new cell contains a single paragraph. Read-only

    Therefore, we add a hyperlink to this paragraph, taking it out of the list, using the paragraphs method.

    hdr_cells = table.rows[0].cells
    
    e = hdr_cells[0].paragraphs[0]
    add_link(paragraph=e, link_to=f"test", text="test", tool_tip="PSD")
    
    e = hdr_cells[1].paragraphs[0]
    add_link(paragraph=e, link_to=f"test", text="test", tool_tip="PSD")
    document.save('link_in_table.docx')