docx_plus.tables.borders¶
Table and cell borders. python-docx has no element class for any of
this — no CT_Border, no CT_TblBorders, no CT_TcBorders, and none
of those tags is registered — so ruling a table has meant writing OOXML
by hand.
Both writers are a full replacement, not a merge: any existing container is discarded first, so an edge you do not name ends up absent. Naming no edges at all removes the element rather than leaving an empty container behind.
Border.space is ignored here
Both writers emit w:space="0", which is what Word does and the
only value its UI can produce for a table. The
Border dataclass defaults space to 24 — a
page-border value — which would otherwise put a third of an inch
between every table edge and its text.
Architecture walkthrough: Table formatting.
docx_plus.tables.borders ¶
Table and cell borders — <w:tblBorders> and <w:tcBorders>.
python-docx has no element class for any of this: there is no
CT_Border, no CT_TblBorders, and no CT_TcBorders anywhere in
the package, and none of those tags is registered, so a border set by
hand round-trips as an anonymous lxml element. Drawing a ruled table
has meant writing the XML yourself.
ECMA-376 uses the same CT_Border shape here as it does for page
borders, so both go through :class:~docx_plus.core.borders.Border and
:func:~docx_plus.core.borders.border_attrs. Tables add the two
inside edges (17.4.39) and cells add the two diagonals (17.4.67).
.. note::
Border.space is ignored for tables and cells — both writers emit
w:space="0", which is what Word does and the only value its UI
can produce. The dataclass default of 24 is a page-border
default and would otherwise leak a third of an inch onto every table
edge.
This module imports only from docx_plus.core (SPEC §9.1).
set_table_borders ¶
set_table_borders(
table: Table,
*,
all_edges: Border | None = None,
top: Border | None = None,
bottom: Border | None = None,
left: Border | None = None,
right: Border | None = None,
inside_h: Border | None = None,
inside_v: Border | None = None,
) -> None
Set the table-level borders on table.
A full replacement, not a merge: any existing <w:tblBorders> is
discarded first, so an edge left unset ends up absent. Calling with
every edge None removes the element rather than writing an empty
container.
These are the table's borders. A cell's own <w:tcBorders>
overrides them for that cell, and a table style supplies them when
neither is present — see :func:set_cell_borders.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
Table
|
A python-docx :class: |
required |
all_edges
|
Border | None
|
Applied to the four outer edges and both inside edges, as a shorthand for the common "rule everything the same way" case. Any explicit edge below overrides it. |
None
|
top
|
Border | None
|
The table's top edge. |
None
|
bottom
|
Border | None
|
The table's bottom edge. |
None
|
left
|
Border | None
|
The table's left edge. |
None
|
right
|
Border | None
|
The table's right edge. |
None
|
inside_h
|
Border | None
|
The horizontal rules between rows. |
None
|
inside_v
|
Border | None
|
The vertical rules between columns. |
None
|
Example
from docx import Document from docx_plus.core import Border from docx_plus.tables import set_table_borders doc = Document() table = doc.add_table(rows=2, cols=2) hairline = Border(style="single", size=4, color="808080") set_table_borders(table, all_edges=hairline, ... top=Border(style="single", size=12))
Source code in docx_plus/tables/borders.py
set_cell_borders ¶
set_cell_borders(
cell: _Cell,
*,
all_edges: Border | None = None,
top: Border | None = None,
bottom: Border | None = None,
left: Border | None = None,
right: Border | None = None,
tl2br: Border | None = None,
tr2bl: Border | None = None,
) -> None
Set the borders on a single cell.
A full replacement, exactly as :func:set_table_borders is. Cell
borders take precedence over the table's, which is how a single
emphasized row or a boxed total is expressed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cell
|
_Cell
|
A python-docx :class: |
required |
all_edges
|
Border | None
|
Applied to the four sides. The diagonals are deliberately not included — they are a decorative "crossed-out cell" mark, never something a caller means by "all borders". |
None
|
top
|
Border | None
|
The cell's top edge. |
None
|
bottom
|
Border | None
|
The cell's bottom edge. |
None
|
left
|
Border | None
|
The cell's left edge. |
None
|
right
|
Border | None
|
The cell's right edge. |
None
|
tl2br
|
Border | None
|
Diagonal from the top-left to the bottom-right corner. |
None
|
tr2bl
|
Border | None
|
Diagonal from the top-right to the bottom-left corner. |
None
|
Example
from docx import Document from docx_plus.core import Border from docx_plus.tables import set_cell_borders doc = Document() table = doc.add_table(rows=2, cols=2) set_cell_borders(table.cell(1, 1), ... top=Border(style="double", size=6))