pythonopenxmlpython-docx

How to turn off cell spacing in a Word document using python docx? (or any other package)


I have an input word document that has some tables with cell spacing set to 0.02". I’d like to turn off that cell spacing (or set it to 0) with the code below that uses the python-docx package. However, when I run the code on the input word file and open the output file, the cell spacing is still turned on and set to 0.02.

I believe the code below should work and set the cell spacing to be off or zero. Why would the cell spacing changes made by python-docx not be reflected in the file?

from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn

def disable_cell_spacing_in_tables(file_path, output_path):
    """
    Disable cell spacing for all tables in the given Word document.
    
    :param file_path: Path to the input Word document.
    :param output_path: Path to save the modified Word document.
    """
    # Open the Word document
    doc = Document(file_path)
    
    # Iterate through all tables in the document
    for table in doc.tables:
        tbl = table._element
        tblPr = tbl.tblPr if tbl.tblPr is not None else OxmlElement('w:tblPr')
        if tbl.tblPr is None:
            tbl.append(tblPr)
        
        # Disable cell spacing
        tbl_cell_spacing = tblPr.find(qn('w:tblCellSpacing'))
        if tbl_cell_spacing is not None:
            tblPr.remove(tbl_cell_spacing)
        tbl_cell_spacing = OxmlElement('w:tblCellSpacing')
        tbl_cell_spacing.set(qn('w:w'), '0')
        tbl_cell_spacing.set(qn('w:type'), 'dxa')
        tblPr.append(tbl_cell_spacing)
    
    # Save the modified document
    doc.save(output_path)
    print(f"Modified document saved to {output_path}")

if __name__ == "__main__":
    input_file_path = 'input.docx'
    output_file_path = 'output.docx'
    disable_cell_spacing_in_tables(input_file_path, output_file_path)

Here is the table option in the Ms Word menu in the output file still set to 0.02".

Table Properties >> Options >> Allow spacing between cells is still turned on


Solution

  • Word not only stores cell spacing for table in table properties tlbPr but also in table row properties trPr. So to remove that, it needs to be removed from both the property settings.

    from docx import Document
    from docx.oxml import OxmlElement
    from docx.oxml.ns import qn
    
    def disable_cell_spacing_in_tables(file_path, output_path):
        """
        Disable cell spacing for all tables in the given Word document.
        
        :param file_path: Path to the input Word document.
        :param output_path: Path to save the modified Word document.
        """
        # Open the Word document
        doc = Document(file_path)
        
        # Iterate through all tables in the document
        for table in doc.tables:
            tbl = table._element
            tblPr = tbl.tblPr if tbl.tblPr is not None else OxmlElement('w:tblPr')
            if tbl.tblPr is None:
                tbl.append(tblPr)
            
            # Disable cell spacing
            tbl_cell_spacing = tblPr.find(qn('w:tblCellSpacing'))
            if tbl_cell_spacing is not None:
                tblPr.remove(tbl_cell_spacing)
            #tbl_cell_spacing = OxmlElement('w:tblCellSpacing')
            #tbl_cell_spacing.set(qn('w:w'), '0')
            #tbl_cell_spacing.set(qn('w:type'), 'dxa')
            #tblPr.append(tbl_cell_spacing)
            
            for row in table.rows:
                tr = row._element
                trPr = tr.trPr if tr.trPr is not None else OxmlElement('w:trPr')
                tbl_cell_spacing = trPr.find(qn('w:tblCellSpacing'))
                if tbl_cell_spacing is not None:
                    trPr.remove(tbl_cell_spacing)
                #tbl_cell_spacing = OxmlElement('w:tblCellSpacing')
                #tbl_cell_spacing.set(qn('w:w'), '0')
                #tbl_cell_spacing.set(qn('w:type'), 'dxa')
                #trPr.append(tbl_cell_spacing)
               
        # Save the modified document
        doc.save(output_path)
        print(f"Modified document saved to {output_path}")
    

    Btw.: If the need is only to remove, there is no need to set it 0.