Repository navigation
Description
w:tblLook is the element that tells Word which parts of a table style to apply — whether the first row is a header row, whether the first column is emphasised, and whether row or column banding is on. Without it, applying a table style produces a table that looks nothing like the style preview in Word.
Today it is written once as a hardcoded string in CT_Tbl._tbl_xml() (src/docx/oxml/table.py:593), with firstRow="1" firstColumn="1" noHBand="0" noVBand="1", and there is no way to read or change it. "w:tblLook" appears in CT_TblPr._tag_seq (src/docx/oxml/table.py:693) but no accessor is declared for it.
So a user who applies "Table Grid" or a banded style to a table gets whatever those five defaults imply, and cannot turn banding on, cannot mark a total row, and cannot switch the first-column emphasis off.
Where the prior art is
lnv42/python-docx, branch feature/tableLooking, adds CT_TblLook with the six attributes, a tblLook accessor on CT_TblPr, and first_row / first_col / last_row / last_col / h_band / v_band properties on Table. It also threads the flags through Table.add_table() as keyword arguments.
It is against upstream v0.8.7 and has bugs — the hBand/vBand property pairs are defined twice as plain methods rather than as a property and its setter, so table.h_band returns a bound method and h_band = True overwrites it. Take the shape, not the code.
Shape
Per ref/xsd/wml.xsd, CT_TblLook is all-attribute, no children:
firstRow, lastRow, firstColumn, lastColumn, noHBand, noVBand s:ST_OnOff
val ST_ShortHexNumber
CT_TblLookinoxml/table.py, registered inoxml/__init__.pytblLook = ZeroOrOne("w:tblLook", successors=...)onCT_TblPr, sliced at the right index of_tag_seq, with a placement testTable.lookreturning a small proxy withfirst_row,last_row,first_column,last_column,horizontal_bandingandvertical_bandingas read/write booleans
The banding pair inverts — horizontal_banding is not noHBand. Make that inversion a property on the proxy and keep the oxml layer faithful to the attribute names.
@w:val is the legacy bitmask carrying the same six flags. Word writes both and keeps them in sync. Decide whether to maintain it on write (Word tolerates its absence, but some older consumers read only the bitmask) and say so in the docstring either way.
Activity
toxicphreAK commentedon Aug 5, 2026
Landed in #139.
Table.lookwith the six flags; the banding pair is inverted in the proxy so the oxml layer stays faithful tow:noHBand/w:noVBand. On the@w:valquestion: it is maintained. Word writes both and keeps them in step, some older consumers read only the bitmask, andCT_TblLook.update_val()says so.