Skip to content

docx_plus.tables.shading

Cell, row, and table background fills. python-docx has no CT_Shd class and does not register the w:shd tag, so the single most common thing anyone wants from a table beyond its text is unreachable.

ECMA-376 models shading as three attributes rather than one colour: a w:fill (the background), a w:val pattern drawn over it, and a w:color for that pattern's foreground. A solid fill — what nearly everyone means — is pattern="clear" with only fill set, which is what Shading defaults to.

Rows have no shading element

CT_TrPr has no w:shd child. Word implements "shade this row" by writing the same <w:shd> into every cell in it, and so does set_row_shading. It iterates the row's <w:tc> elements rather than Row.cells, so a cell spanning several grid columns is visited once rather than once per column.

Architecture walkthrough: Table formatting.

docx_plus.tables.shading

Table, row, and cell shading — <w:shd>.

python-docx has no CT_Shd class and does not register the w:shd tag, so cell background fills — the single most common thing anyone wants from a table beyond its text — have to be written as raw XML.

ECMA-376 17.4.32 models shading as three attributes rather than one colour: a w:fill (the background), a w:val pattern drawn over it, and a w:color for that pattern's foreground. Solid fills, which is what nearly everyone means, are pattern="clear" with only fill set — so :class:Shading defaults to exactly that and a plain Shading(fill="D9E2F3") does the obvious thing.

.. note:: Rows have no shading element. CT_TrPr (17.4.82) has no w:shd child — Word implements "shade this row" by writing the same <w:shd> into every cell in it, and so does :func:set_row_shading.

This module imports only from docx_plus.core (SPEC §9.1).

Shading dataclass

Shading(fill: str = 'auto', pattern: str = 'clear', color: str = 'auto')

A background fill, optionally with a pattern drawn over it.

Attributes:

Name Type Description
fill str

Background colour as "RRGGBB" hex, or "auto" (default) to let the consumer choose. This is the attribute that produces a solid block of colour.

pattern str

ECMA-376 17.18.78 ST_Shd value. "clear" (default) means no pattern — just fill. "nil" removes shading, and the "pct5""pct95" family blends color into fill by that percentage.

color str

Foreground colour of pattern, as "RRGGBB" hex or "auto" (default). Has no visible effect while pattern is "clear".

Raises:

Type Description
ValueError

If fill or color is not "auto" or a six-hex-digit "RRGGBB" string, or if pattern is not a bare identifier.

Example

from docx_plus.tables import Shading header = Shading(fill="2F5496") hatched = Shading(fill="FFFFFF", pattern="pct25", color="808080")

__post_init__

__post_init__() -> None

Validate the fields against their ECMA-376 simple types.

Source code in docx_plus/tables/shading.py
def __post_init__(self) -> None:
    """Validate the fields against their ECMA-376 simple types."""
    for name in ("fill", "color"):
        value = getattr(self, name)
        if not _HEX_COLOR_RE.match(value):
            raise ValueError(
                f"Shading.{name} must be 'auto' or a six-hex-digit 'RRGGBB' "
                f"string; got {value!r}"
            )
    if not _PATTERN_RE.match(self.pattern):
        raise ValueError(
            "Shading.pattern must be an ECMA-376 17.18.78 ST_Shd value such as "
            f"clear/nil/solid/pct25; got {self.pattern!r}"
        )

set_table_shading

set_table_shading(table: Table, shading: Shading | None) -> None

Set the table-level shading on table.

Idempotent — replaces any existing <w:shd>. Passing None removes it.

Table-level shading sits below row-banding from a table style and below any cell's own shading, so it reads as a default rather than an override.

Parameters:

Name Type Description Default
table Table

A python-docx :class:~docx.table.Table.

required
shading Shading | None

The shading to apply, or None to remove it.

required
Example

from docx import Document from docx_plus.tables import Shading, set_table_shading doc = Document() set_table_shading(doc.add_table(rows=1, cols=1), Shading(fill="F2F2F2"))

Source code in docx_plus/tables/shading.py
def set_table_shading(table: Table, shading: Shading | None) -> None:
    """Set the table-level shading on ``table``.

    Idempotent — replaces any existing ``<w:shd>``. Passing ``None``
    removes it.

    Table-level shading sits *below* row-banding from a table style and
    below any cell's own shading, so it reads as a default rather than
    an override.

    Args:
        table: A python-docx :class:`~docx.table.Table`.
        shading: The shading to apply, or ``None`` to remove it.

    Example:
        >>> from docx import Document
        >>> from docx_plus.tables import Shading, set_table_shading
        >>> doc = Document()
        >>> set_table_shading(doc.add_table(rows=1, cols=1), Shading(fill="F2F2F2"))
    """
    _write_shading(table._tbl.tblPr, shading, _TBL_PR_AFTER_SHD)

set_row_shading

set_row_shading(row: _Row, shading: Shading | None) -> None

Shade every cell in row.

There is no row-level shading element in the format — CT_TrPr has no w:shd child — so this writes the same <w:shd> into each of the row's cells, which is what Word's UI does for a selected row.

Iterates the row's <w:tc> elements directly rather than Row.cells, so a cell spanning several grid columns is visited once rather than once per column it covers.

Parameters:

Name Type Description Default
row _Row

A python-docx :class:~docx.table._Row.

required
shading Shading | None

The shading to apply, or None to remove it from every cell in the row.

required
Example

from docx import Document from docx_plus.tables import Shading, set_row_shading doc = Document() table = doc.add_table(rows=2, cols=3) set_row_shading(table.rows[0], Shading(fill="2F5496"))

Source code in docx_plus/tables/shading.py
def set_row_shading(row: _Row, shading: Shading | None) -> None:
    """Shade every cell in ``row``.

    There is no row-level shading element in the format — ``CT_TrPr``
    has no ``w:shd`` child — so this writes the same ``<w:shd>`` into
    each of the row's cells, which is what Word's UI does for a selected
    row.

    Iterates the row's ``<w:tc>`` elements directly rather than
    ``Row.cells``, so a cell spanning several grid columns is visited
    once rather than once per column it covers.

    Args:
        row: A python-docx :class:`~docx.table._Row`.
        shading: The shading to apply, or ``None`` to remove it from
            every cell in the row.

    Example:
        >>> from docx import Document
        >>> from docx_plus.tables import Shading, set_row_shading
        >>> doc = Document()
        >>> table = doc.add_table(rows=2, cols=3)
        >>> set_row_shading(table.rows[0], Shading(fill="2F5496"))
    """
    for tc in row._tr.tc_lst:
        _write_shading(tc.get_or_add_tcPr(), shading, _TC_PR_AFTER_SHD)

set_cell_shading

set_cell_shading(cell: _Cell, shading: Shading | None) -> None

Set the shading on a single cell.

Idempotent — replaces any existing <w:shd>. Passing None removes it.

Parameters:

Name Type Description Default
cell _Cell

A python-docx :class:~docx.table._Cell.

required
shading Shading | None

The shading to apply, or None to remove it.

required
Example

from docx import Document from docx_plus.tables import Shading, set_cell_shading doc = Document() table = doc.add_table(rows=2, cols=2) set_cell_shading(table.cell(0, 0), Shading(fill="2F5496"))

Source code in docx_plus/tables/shading.py
def set_cell_shading(cell: _Cell, shading: Shading | None) -> None:
    """Set the shading on a single ``cell``.

    Idempotent — replaces any existing ``<w:shd>``. Passing ``None``
    removes it.

    Args:
        cell: A python-docx :class:`~docx.table._Cell`.
        shading: The shading to apply, or ``None`` to remove it.

    Example:
        >>> from docx import Document
        >>> from docx_plus.tables import Shading, set_cell_shading
        >>> doc = Document()
        >>> table = doc.add_table(rows=2, cols=2)
        >>> set_cell_shading(table.cell(0, 0), Shading(fill="2F5496"))
    """
    _write_shading(cell._tc.get_or_add_tcPr(), shading, _TC_PR_AFTER_SHD)

shading_attrs

shading_attrs(shading: Shading) -> dict[str, str]

Serialize shading to the CT_Shd attribute mapping.

Parameters:

Name Type Description Default
shading Shading

The shading to serialize.

required

Returns:

Type Description
dict[str, str]

A {"w:val": ..., "w:color": ..., "w:fill": ...} mapping in

dict[str, str]

the attribute order Word writes.

Source code in docx_plus/tables/shading.py
def shading_attrs(shading: Shading) -> dict[str, str]:
    """Serialize ``shading`` to the ``CT_Shd`` attribute mapping.

    Args:
        shading: The shading to serialize.

    Returns:
        A ``{"w:val": ..., "w:color": ..., "w:fill": ...}`` mapping in
        the attribute order Word writes.
    """
    return {
        "w:val": shading.pattern,
        "w:color": shading.color,
        "w:fill": shading.fill,
    }