Skip to content

section

section

The Section object and related proxy classes.

_PageBorders

_PageBorders(sectPr: CT_SectPr)

Bases: _Borders

The border edges drawn around the pages of a section, section.page_borders.

Beyond the four edges, w:pgBorders carries three of its own settings — see offset_from, display and z_order.

Source code in src/docx/section.py
def __init__(self, sectPr: CT_SectPr):
    super().__init__(CT_PageBorders.edges)
    self._sectPr = sectPr

display property writable

display: str | None

Which pages the border is drawn on, or None when not set.

One of "allPages", "firstPage" or "notFirstPage". Word's default, when the attribute is absent, is all pages.

offset_from property writable

offset_from: str | None

What the border is measured from, "page" or "text", or None.

A certificate frame is measured from the page edge; a border that should track the text block is measured from the text.

z_order property writable

z_order: str | None

Whether the border is drawn "front" of or "back" of the page content.

None when not set.

Section

Section(sectPr: CT_SectPr, document_part: DocumentPart)

Document section, providing access to section and page setup settings.

Also provides access to headers and footers.

Source code in src/docx/section.py
def __init__(self, sectPr: CT_SectPr, document_part: DocumentPart):
    super(Section, self).__init__()
    self._sectPr = sectPr
    self._document_part = document_part

bidi property writable

bidi: bool | None

True when the default base direction for this section is right-to-left.

This is the section-level default; a paragraph's own paragraph_format.bidi overrides it. None means inherited, not False.

text_direction property writable

text_direction: WD_TEXT_DIRECTION | None

Default flow direction of the text in this section, or None when inherited.

Distinct from bidi: this says which way the lines run and whether the glyphs are rotated, not which direction the text reads in.

bottom_margin property writable

bottom_margin: Length | None

Read/write. Bottom margin for pages in this section, in EMU.

None when no bottom margin has been specified. Assigning None removes any bottom-margin setting.

column_count property writable

column_count: int

Read/write. The number of text columns in this section.

1 for an ordinary single-column section, which is also what an absent w:cols element means. Assigning a count leaves the columns of equal width; use set_column_widths for unequal ones.

column_separator property writable

column_separator: bool

Read/write. True if a vertical rule is drawn between the columns.

column_spacing property writable

column_spacing: Length | None

Read/write. The space between columns, in EMU, or None if not specified.

For columns of unequal width this is the fallback; each column can carry its own spacing, given through set_column_widths.

column_widths property

column_widths: tuple[Length | None, ...]

The width of each column, when the columns are of unequal width.

An empty tuple for equal-width columns, whose width Word derives from the page width, the margins and the column spacing rather than stating.

different_first_page_header_footer: bool

True if this section displays a distinct first-page header and footer.

Read/write. The definition of the first-page header and footer are accessed using first_page_header and first_page_footer respectively.

even_page_footer: _Footer

_Footer object defining footer content for even pages.

The content of this footer definition is ignored unless the document setting odd_and_even_pages_header_footer is set True.

even_page_header property

even_page_header: _Header

_Header object defining header content for even pages.

The content of this header definition is ignored unless the document setting odd_and_even_pages_header_footer is set True.

first_page_footer: _Footer

_Footer object defining footer content for the first page of this section.

The content of this footer definition is ignored unless the property different_first_page_header_footer is set True.

first_page_header property

first_page_header: _Header

_Header object defining header content for the first page of this section.

The content of this header definition is ignored unless the property different_first_page_header_footer is set True.

footer_distance property writable

footer_distance: Length | None

Distance from bottom edge of page to bottom edge of the footer.

Read/write. None if no setting is present in the XML.

watermarks property

watermarks: List[Watermark]

The watermarks in force for this section, in header order.

Empty when the section has none. Ordinarily one per header type, all saying the same thing; they are separate objects because they are separate shapes in separate headers.

gutter property writable

gutter: Length | None

Length object representing page gutter size in English Metric Units.

Read/write. The page gutter is extra spacing added to the inner margin to ensure even margins after page binding. Generally only used in book-bound documents with double-sided and facing pages.

This setting applies to all pages in this section.

header_distance property writable

header_distance: Length | None

Distance from top edge of page to top edge of header.

Read/write. None if no setting is present in the XML. Assigning None causes default value to be used.

left_margin property writable

left_margin: Length | None

Length object representing the left margin for all pages in this section in English Metric Units.

orientation property writable

orientation: WD_ORIENTATION

WdOrientation member specifying page orientation for this section.

One of WD_ORIENT.PORTRAIT or WD_ORIENT.LANDSCAPE.

Assigning a different orientation also exchanges page_width and page_height, so the page is actually rotated:

section.page_width, section.page_height    # -- (8.5in, 11in) --
section.orientation = WD_ORIENT.LANDSCAPE
section.page_width, section.page_height    # -- (11in, 8.5in) --

Underneath, w:orient and the w:w/w:h page dimensions are independent attributes, and setting only the first leaves a section declared landscape at portrait dimensions — which Word renders as portrait. Set page_width and page_height explicitly afterwards for a page size that is not simply the rotation of the current one. Margins (left_margin and friends) are not moved.

page_height property writable

page_height: Length | None

Total page height used for this section.

This value is inclusive of all edge spacing values such as margins.

Page orientation is taken into account, so for example, its expected value would be Inches(8.5) for letter-sized paper when orientation is landscape.

page_width property writable

page_width: Length | None

Total page width used for this section.

This value is like "paper size" and includes all edge spacing values such as margins.

Page orientation is taken into account, so for example, its expected value would be Inches(11) for letter-sized paper when orientation is landscape.

right_margin property writable

right_margin: Length | None

Length object representing the right margin for all pages in this section in English Metric Units.

start_type property writable

start_type: WD_SECTION_START

Type of page-break (if any) inserted at the start of this section.

For exmple, WD_SECTION_START.ODD_PAGE if the section should begin on the next odd page, possibly inserting two page-breaks instead of one.

top_margin property writable

top_margin: Length | None

Length object representing the top margin for all pages in this section in English Metric Units.

page_borders

page_borders() -> _PageBorders

The border edges drawn around the pages of this section:

section.page_borders["top"].line = WD_LINE_STYLE.DOUBLE
section.page_borders.offset_from = "page"

This is how a certificate or a title page gets its frame. Only the four sides are admitted, unlike a paragraph's borders.

Source code in src/docx/section.py
@lazyproperty
def page_borders(self) -> _PageBorders:
    """The border edges drawn around the pages of this section::

        section.page_borders["top"].line = WD_LINE_STYLE.DOUBLE
        section.page_borders.offset_from = "page"

    This is how a certificate or a title page gets its frame. Only the four sides
    are admitted, unlike a paragraph's borders.
    """
    return _PageBorders(self._sectPr)

footer

footer() -> _Footer

_Footer object representing default page footer for this section.

The default footer is used for odd-numbered pages when separate odd/even footers are enabled. It is used for both odd and even-numbered pages otherwise.

Source code in src/docx/section.py
@lazyproperty
def footer(self) -> _Footer:
    """|_Footer| object representing default page footer for this section.

    The default footer is used for odd-numbered pages when separate odd/even footers
    are enabled. It is used for both odd and even-numbered pages otherwise.
    """
    return _Footer(self._sectPr, self._document_part, WD_HEADER_FOOTER.PRIMARY)

add_text_watermark

add_text_watermark(
    text: str,
    *,
    font: str = "Calibri",
    font_size: Length | int | None = None,
    color: str = "C0C0C0",
    opacity: float | None = None,
    angle: float = 315,
    width: Length | int = Pt(468),
    height: Length | int = Pt(234),
    bold: bool = False,
    italic: bool = False,
) -> List[Watermark]

Add a text watermark to this section, returning the watermarks added.

The watermark goes into all three header types — default, first-page and even-page — so it does not vanish on a page that uses a different header:

section.add_text_watermark("DRAFT")
section.add_text_watermark("CONFIDENTIAL", color="FF0000", angle=0)

color is an RGB hex string; Word's own "Semitransparent" watermark is simply a light grey, which is the default here. opacity additionally sets true VML transparency, between 0 and 1. angle is the rotation in degrees, 315 giving Word's diagonal watermark and 0 a horizontal one.

The text is stretched to fill a box of width by height, which is how Word sizes a watermark; the defaults are Word's own. Passing font_size renders the text at that size instead of stretching it.

Where this section's headers are inherited from an earlier section, the watermark is written into the header actually in force, which that earlier section shares. An inherited header is the same header, so there is no way to mark up one section's copy of it alone without first setting is_linked_to_previous = False.

Source code in src/docx/section.py
def add_text_watermark(
    self,
    text: str,
    *,
    font: str = "Calibri",
    font_size: Length | int | None = None,
    color: str = "C0C0C0",
    opacity: float | None = None,
    angle: float = 315,
    width: Length | int = Pt(468),
    height: Length | int = Pt(234),
    bold: bool = False,
    italic: bool = False,
) -> List[Watermark]:
    """Add a text watermark to this section, returning the watermarks added.

    The watermark goes into all three header types — default, first-page and
    even-page — so it does not vanish on a page that uses a different header::

        section.add_text_watermark("DRAFT")
        section.add_text_watermark("CONFIDENTIAL", color="FF0000", angle=0)

    `color` is an RGB hex string; Word's own "Semitransparent" watermark is simply a
    light grey, which is the default here. `opacity` additionally sets true VML
    transparency, between 0 and 1. `angle` is the rotation in degrees, 315 giving
    Word's diagonal watermark and 0 a horizontal one.

    The text is stretched to fill a box of `width` by `height`, which is how Word
    sizes a watermark; the defaults are Word's own. Passing `font_size` renders the
    text at that size instead of stretching it.

    Where this section's headers are inherited from an earlier section, the
    watermark is written into the header actually in force, which that earlier
    section shares. An inherited header is the same header, so there is no way to
    mark up one section's copy of it alone without first setting
    `is_linked_to_previous = False`.
    """
    from docx.watermark import add_text_watermark, iter_watermark_headers

    return add_text_watermark(
        iter_watermark_headers([self]),
        text,
        font=font,
        font_size=font_size,
        color=color,
        opacity=opacity,
        angle=angle,
        width=width,
        height=height,
        bold=bold,
        italic=italic,
    )

add_image_watermark

add_image_watermark(
    image_path_or_stream: str | PathLike[str] | IO[bytes],
    *,
    width: Length | int | None = None,
    height: Length | int | None = None,
    washout: bool = True,
    scale: float = 1.0,
) -> List[Watermark]

Add an image watermark to this section, returning the watermarks added.

As with add_text_watermark, all three header types get the watermark.

width and height scale the image the same way Run.add_picture does, defaulting to its native size; scale multiplies whatever that works out to. washout applies Word's brightness-and-contrast correction, which is what turns a logo into a pale background image rather than an opaque one over the text.

Source code in src/docx/section.py
def add_image_watermark(
    self,
    image_path_or_stream: str | os.PathLike[str] | IO[bytes],
    *,
    width: Length | int | None = None,
    height: Length | int | None = None,
    washout: bool = True,
    scale: float = 1.0,
) -> List[Watermark]:
    """Add an image watermark to this section, returning the watermarks added.

    As with :meth:`add_text_watermark`, all three header types get the watermark.

    `width` and `height` scale the image the same way :meth:`.Run.add_picture` does,
    defaulting to its native size; `scale` multiplies whatever that works out to.
    `washout` applies Word's brightness-and-contrast correction, which is what turns
    a logo into a pale background image rather than an opaque one over the text.
    """
    from docx.watermark import add_image_watermark, iter_watermark_headers

    return add_image_watermark(
        iter_watermark_headers([self]),
        image_path_or_stream,
        width=width,
        height=height,
        washout=washout,
        scale=scale,
    )

remove_watermark

remove_watermark() -> int

Remove every watermark from this section, returning how many were removed.

Source code in src/docx/section.py
def remove_watermark(self) -> int:
    """Remove every watermark from this section, returning how many were removed."""
    from docx.watermark import iter_watermark_headers, remove_watermarks

    return remove_watermarks(iter_watermark_headers([self]))

iter_headers_footers

iter_headers_footers() -> Iterator[_Header | _Footer]

Generate all six header and footer objects of this section.

The default, first-page and even-page header come first, then the three footers. All six are generated whether or not they are in use: whether a first-page header is shown depends on different_first_page_header_footer, and whether it is defined here or inherited from the prior section is is_linked_to_previous. This is for code that needs to visit each of them, such as a document-wide search.

Source code in src/docx/section.py
def iter_headers_footers(self) -> Iterator[_Header | _Footer]:
    """Generate all six header and footer objects of this section.

    The default, first-page and even-page header come first, then the three footers.
    All six are generated whether or not they are in use: whether a first-page
    header is shown depends on :attr:`different_first_page_header_footer`, and
    whether it is defined here or inherited from the prior section is
    :attr:`~._BaseHeaderFooter.is_linked_to_previous`. This is for code that needs
    to visit each of them, such as a document-wide search.
    """
    yield self.header
    yield self.first_page_header
    yield self.even_page_header
    yield self.footer
    yield self.first_page_footer
    yield self.even_page_footer

header

header() -> _Header

_Header object representing default page header for this section.

The default header is used for odd-numbered pages when separate odd/even headers are enabled. It is used for both odd and even-numbered pages otherwise.

Source code in src/docx/section.py
@lazyproperty
def header(self) -> _Header:
    """|_Header| object representing default page header for this section.

    The default header is used for odd-numbered pages when separate odd/even headers
    are enabled. It is used for both odd and even-numbered pages otherwise.
    """
    return _Header(self._sectPr, self._document_part, WD_HEADER_FOOTER.PRIMARY)

iter_inner_content

iter_inner_content() -> Iterator[Paragraph | Table]

Generate each Paragraph or Table object in this section.

Items appear in document order.

Source code in src/docx/section.py
def iter_inner_content(self) -> Iterator[Paragraph | Table]:
    """Generate each Paragraph or Table object in this `section`.

    Items appear in document order.
    """
    for element in self._sectPr.iter_inner_content():
        yield (Paragraph(element, self) if isinstance(element, CT_P) else Table(element, self))

set_column_widths

set_column_widths(
    widths: Sequence[Length],
    spacings: Sequence[Length] | None = None,
) -> None

Lay this section out in columns of the given widths.

spacings gives the space following each column and defaults to the section's .column_spacing for every column. It must be the same length as widths when given; the value for the last column is written but has no visible effect.

The equal-width case is the common one and is better expressed by assigning .column_count, which this replaces. Pass a single width to go back to one column.

Source code in src/docx/section.py
def set_column_widths(
    self, widths: Sequence[Length], spacings: Sequence[Length] | None = None
) -> None:
    """Lay this section out in columns of the given `widths`.

    `spacings` gives the space following each column and defaults to the section's
    `.column_spacing` for every column. It must be the same length as `widths` when
    given; the value for the last column is written but has no visible effect.

    The equal-width case is the common one and is better expressed by assigning
    `.column_count`, which this replaces. Pass a single width to go back to one
    column.
    """
    if not widths:
        raise ValueError("at least one column width is required")
    if spacings is not None and len(spacings) != len(widths):
        raise ValueError(
            "spacings must have one value per column, got %d for %d columns"
            % (len(spacings), len(widths))
        )

    cols = self._sectPr.get_or_add_cols()
    cols.clear_cols()
    cols.num = len(widths)
    cols.equalWidth = False
    for idx, width in enumerate(widths):
        col = cols.add_col()
        col.w = width
        if spacings is not None:
            col.space = spacings[idx]

Sections

Sections(
    document_elm: CT_Document, document_part: DocumentPart
)

Bases: Sequence[Section]

Sequence of Section objects corresponding to the sections in the document.

Supports len(), iteration, and indexed access.

Source code in src/docx/section.py
def __init__(self, document_elm: CT_Document, document_part: DocumentPart):
    super(Sections, self).__init__()
    self._document_elm = document_elm
    self._document_part = document_part

_BaseHeaderFooter

_BaseHeaderFooter(
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
)

Bases: BlockItemContainer

Base class for header and footer classes.

Source code in src/docx/section.py
def __init__(
    self,
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
):
    self._sectPr = sectPr
    self._document_part = document_part
    self._hdrftr_index = header_footer_index

is_linked_to_previous property writable

is_linked_to_previous: bool

True if this header/footer uses the definition from the prior section.

False if this header/footer has an explicit definition.

Assigning True to this property removes the header/footer definition for this section, causing it to "inherit" the corresponding definition of the prior section. Assigning False causes a new, empty definition to be added for this section, but only if no definition is already present.

part property

The HeaderPart or FooterPart for this header/footer.

This overrides BlockItemContainer.part and is required to support image insertion and perhaps other content like hyperlinks.

_Footer(
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
)

Bases: _BaseHeaderFooter

Page footer, used for all three types (default, even-page, and first-page).

Note that, like a document or table cell, a footer must contain a minimum of one paragraph and a new or otherwise "empty" footer contains a single empty paragraph. This first paragraph can be accessed as footer.paragraphs[0] for purposes of adding content to it. Using add_paragraph() by itself to add content will leave an empty paragraph above the newly added one.

Source code in src/docx/section.py
def __init__(
    self,
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
):
    self._sectPr = sectPr
    self._document_part = document_part
    self._hdrftr_index = header_footer_index

_Header

_Header(
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
)

Bases: _BaseHeaderFooter

Page header, used for all three types (default, even-page, and first-page).

Note that, like a document or table cell, a header must contain a minimum of one paragraph and a new or otherwise "empty" header contains a single empty paragraph. This first paragraph can be accessed as header.paragraphs[0] for purposes of adding content to it. Using add_paragraph() by itself to add content will leave an empty paragraph above the newly added one.

Source code in src/docx/section.py
def __init__(
    self,
    sectPr: CT_SectPr,
    document_part: DocumentPart,
    header_footer_index: WD_HEADER_FOOTER,
):
    self._sectPr = sectPr
    self._document_part = document_part
    self._hdrftr_index = header_footer_index