Search code examples
pythonms-wordpython-docx

How to make page numbers start from page N at number 1?


Using python-docx how to make page numbers start from another page that the first one but still start at 1?

Using answer to this question, I have come up with the below reproducible example.

It starts the numbering at the correct page (page 4) but it starts it from number 4 and I want it to be number 1. How to solve thos?

import docx
from docx.enum.section import WD_SECTION
from docx.oxml import OxmlElement, ns

def create_element(name):
    return OxmlElement(name)

def create_attribute(element, name, value):
    element.set(ns.qn(name), value)


def add_page_number(section):
    p = section.footer.paragraphs[0]
    p.alignment = 1
    p.style.font.size = Pt(9)
    p.style.font.name = DEFAULT_FONT_NAME

    run = p.add_run()
    fldChar1 = create_element('w:fldChar')
    create_attribute(fldChar1, 'w:fldCharType', 'begin')

    instrText = create_element('w:instrText')
    create_attribute(instrText, 'xml:space', 'preserve')
    instrText.text = "PAGE"

    fldChar2 = create_element('w:fldChar')
    create_attribute(fldChar2, 'w:fldCharType', 'end')

    run._r.append(fldChar1)
    run._r.append(instrText)
    run._r.append(fldChar2)

document = docx.Document()

# first blank page
document.add_page_break()

# second blank page
document.add_page_break()

# 3rd page with some text
p = document.add_paragraph("Title")
document.add_page_break()

# page from which I want to get page numbers:
document.add_section(WD_SECTION.NEW_PAGE)
document.sections[1].footer.is_linked_to_previous = False
document.add_paragraph("text of my first page")

# add page numbers
add_page_number(document.sections[1])

# save
document.save('example.docx')

EDIT: I just found this and think I need to use w:pgNumType with w:start but could not get it to work neither.


Solution

  • First define a new section from which you will want to number pages: page_number_starting_at_section. Then disable the linking prior to that one and then add the page numbers.

    page_number_starting_at_section = 2
    
    # Disable linking headers and footers to the previous section for the preamble
    for i in range(0, page_number_starting_at_section + 1):
        document.sections[i].footer.is_linked_to_previous = False
        document.sections[i].header.is_linked_to_previous = False
        document.sections[i].even_page_footer.is_linked_to_previous = False
        document.sections[i].even_page_header.is_linked_to_previous = False
    
    # Configure the section to start page numbering from 1
    section = document.sections[page_number_starting_at_section]
    sectPr = section._sectPr
    pgNumType = OxmlElement("w:pgNumType")
    pgNumType.set(qn("w:start"), "1")
    sectPr.append(pgNumType)
    add_page_numbers(section.footer)