1

I am going through the tutorial and documentation of python-docx.

However, I can't find any reference to how I can specify and manipulate the border appearance of a table created in a Microsoft Word document.

When i use the following code:

from docx import Document
from docx.shared import Inches

document = Document()

################################
################################
################################

table = document.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'

row_cells = table.add_row().cells
row_cells[0].text = 'Str0'
row_cells[1].text = 'Str1'
row_cells[2].text = 'Str2'

row2_cells = table.add_row().cells
row2_cells[0].text = 'Str00'
row2_cells[1].text = 'Str11'
row2_cells[2].text = 'Str22'

################################
################################
################################

document.save('demo.docx')

The resulting docx file shows the 3x3 table with header. Currently there is no black border (inner or outer) on this table.

How can I specify an upper and lower border around the header, a lower border to wrap around the table, as well as an inner vertical border?

For example:

enter image descpiption here

KubiK888
  • 4,377
  • 14
  • 61
  • 115

2 Answers2

7

Unfortunately, there is no way to directly manipulate table borders from within python-docx. You basically need to use a style, which specifies these. The style must already exist in Word.

In order to generate a table style to your liking, you need to manually create a new empty document in Word, customize one of the existing table styles there (e.g. Colorful Shading), and add a table using this modified style. Next, you delete this table and save the file (say example.docx) on your disk. This is necessary for the modified style to be saved in the document.

All you have to do then is load the file using python-docx and add a new table, which will reference the (modified) table style:

document = Document('example.docx')
table = document.add_table(rows=1, cols=3)
table.style = 'ColorfulShading'

See also Understanding styles in the documentation for details on how styles in Word work.

4

Since the python-docx library does not currently have a function method to directly set the cell border, I have found this solution from this web (highly recomended lecture):

from docx.table import _Cell
from docx.oxml import OxmlElement
from docx.oxml.ns import qn

def set_cell_border(cell: _Cell, **kwargs):
    """
    Set cell`s border
    Usage:
    set_cell_border(
        cell,
        top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},
        bottom={"sz": 12, "color": "#00FF00", "val": "single"},
        start={"sz": 24, "val": "dashed", "shadow": "true"},
        end={"sz": 12, "val": "dashed"},
    )
    """
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()

    # check for tag existnace, if none found, then create one
    tcBorders = tcPr.first_child_found_in("w:tcBorders")
    if tcBorders is None:
        tcBorders = OxmlElement('w:tcBorders')
        tcPr.append(tcBorders)
 
    # list over all available tags
    for edge in ('start', 'top', 'end', 'bottom', 'insideH', 'insideV'):
        edge_data = kwargs.get(edge)
        if edge_data:
            tag = 'w:{}'.format(edge)
 
            # check for tag existnace, if none found, then create one
            element = tcBorders.find(qn(tag))
            if element is None:
                element = OxmlElement(tag)
                tcBorders.append(element)
 
            # looks like order of attributes is important
            for key in ["sz", "val", "color", "space", "shadow"]:
                if key in edge_data:
                    element.set(qn('w:{}'.format(key)), str(edge_data[key]))

The list of optional keyword arguments for editing the cell borders are listed here.

Facu
  • 101
  • 6