Search code examples
pythonpython-docx

Python-docx How to set space after paragraphs of the same style


I have noticed when using python-docx that if I apply a style to to each paragraph in order, but have a style of space_after = Pt(12), Word does not accept the space_after setting. I've noticed in the Paragraph options that "Don't add space between paragraphs of the same style" is checked. Is there any way to get around this so the space_after setting will be applied?

I've used a new line character at the end of my text, but I will not always want a new line. Sometimes, I might want a partial line, or a specific size.


Solution

  • I've built a document with a few paragraphs of the same style ("Normal") and various space_after:

    enter image description here

    Select all paragraphs and toggle the "Dont' add space between paragraphs of the same style" to checked.

    Now it looks like so:

    enter image description here

    Save and close the document from Word, then examine it via docx:

    >>> from docx import Document
    >>> document = Document(r'c:\debug\doc1.docx')
    >>> for p in document.paragraphs:
    ...     print(p.paragraph_format.space_after)
    ...
    635000
    None
    None
    

    So, clearly the space_after is retained, but it's not being observed in the document as it's overridden by the checkbox option. This is given by the <w:contextualSpacing/> element of the <w:pPr> (I notice this by examining the \word\document.xml part of the Docx).

    <w:p xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" w:rsidR="00E00961" w:rsidRDefault="00174F18">
      <w:pPr>   
        <w:spacing w:after="1000"/>   
        <w:contextualSpacing/> 
      </w:pPr>  
      <w:bookmarkStart w:id="0" w:name="_GoBack"/> 
      <w:r>   
        <w:t>hello, world!
        </w:t>  
      </w:r>
    </w:p>
    

    You can remove these from the underlying XML like so:

    for p in document.paragraphs:
        p_element = p._element
        cspacing = p_element.xpath(r'w:pPr/w:contextualSpacing')[0]
        cspacing.getparent().remove(cspacing)
    

    After removing those elements, open the document again and observe the toggle has been turned off, and the paragraphs observe the space_after:

    enter image description here