Setting pgNumType property in python-docx is without effect

半腔热情 提交于 2021-01-27 10:46:16

问题


I'm trying to set page numbers in a word document using python-docx. I found an attribute pgNumType (pageNumberType), which I'm setting with this code:

document = Document()
section = document.add_section(WD_SECTION.CONTINUOUS)
sections = document.sections

sectPr = sections[0]._sectPr

pgNumType = OxmlElement('w:pgNumType')
pgNumType.set(qn('w:fmt'), 'decimal')
pgNumType.set(qn('w:start'), '1')

sectPr.append(pgNumType)

This code does nothing, no page numbers are in the output document. I did the same with a lnNumType attribute which is for line numbers and it worked fine. So what is it with the pgNumType attribute? The program executes without error, so the attribute exists. But anyone knows why it has no effect?


回答1:


While your page style setting is fine, but it does not automatically insert a page number field anywhere in your document. Normally, page numbers appear in a header or a footer, but unfortunately, python-docx does not currently support headers, footers or fields. The former two appear to be an ongoing work in progress: https://github.com/python-openxml/python-docx/issues/104.

The linked issue mentions a number of workarounds. The one I have found to be most robust is to create an otherwise blank document with the headers and footers set up exactly the way you want in MS Word. You can then load and append to that document instead of the default template that docx.Document returns.

This technique is implied to be the suggested method for editing headers in the official documentation:

A lot of how a document looks is determined by the parts that are left when you delete all the content. Things like styles and page headers and footers are contained separately from the main content, allowing you to place a good deal of customization in your starting document that then appears in the document you produce.




回答2:


@T.Poe I was working on same problem.

new_section = document.add_section()  # Added new section for assigning different footer on each page.
sectPr = new_section._sectPr

pgNumType = OxmlElement('w:pgNumType')
pgNumType.set(qn('w:fmt'), 'decimal')
pgNumType.set(qn('w:start'), '1')

sectPr.append(pgNumType)

new_footer = new_section.footer  # Get footer-area of the recent section in document
new_footer.is_linked_to_previous = False  
footer_para = new_footer.add_paragraph()  
run_footer = footer_para.add_run("Your footer here")
_add_number_range(run_footer)
font = run_footer.font
font.name = 'Arial'
font.size = Pt(8)
footer_para.paragraph_format.page_break_before = True

This worked for me :) I don't know whats not working for you. I just created a new section

Some code for function I used to define field is as follows:

def _add_field(run, field):
    """ add a field to a run
    """
    fldChar1 = OxmlElement('w:fldChar')  # creates a new element
    fldChar1.set(qn('w:fldCharType'), 'begin')  # sets attribute on element
    instrText = OxmlElement('w:instrText')
    instrText.set(qn('xml:space'), 'preserve')  # sets attribute on element
    instrText.text = field

    fldChar2 = OxmlElement('w:fldChar')
    fldChar2.set(qn('w:fldCharType'), 'separate')
    t = OxmlElement('w:t')
    t.text = "Seq"
    fldChar2.append(t)

    fldChar4 = OxmlElement('w:fldChar')
    fldChar4.set(qn('w:fldCharType'), 'end')


    r_element = run._r
    r_element.append(fldChar1)
    r_element.append(instrText)
    r_element.append(fldChar2)
    r_element.append(fldChar4)



def _add_number_range(run):
    """ add a number range field to a run
    """
    _add_field(run, r'Page')


来源:https://stackoverflow.com/questions/50776715/setting-pgnumtype-property-in-python-docx-is-without-effect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!