[Python] Changes to table with python-docx not persistent in Python 3.11

Discussão em 'Python' iniciado por Stack, Março 21, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using python-docx (v1.1.2) and Python 3.11.3 to work on a tool to fix a bunch of Word documents automatically. I've been able to update fonts, titles, texts, headers and footers and tables (their borders).

    However, some tables, and I haven't found the pattern of why this happens, are not updated. This is the snippet I've developed.

    def update_borders(table):
    #namespaces used when updating the elements (the changes are not persistent if not used)
    NSMAP = {"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
    WORD_NS = NSMAP["w"]
    # sample color map
    BORDER_COLOR_MAP = { "auto": "F07E26" }
    small_table = len(table.rows) == 1 and len(table.columns) == 2
    tbl_xml = table._element
    tbl_pr = tbl_xml.find(f'{{{WORD_NS}}}tblPr')
    if tbl_pr is None:
    tbl_pr = etree.SubElement(tbl_xml, f"{{{WORD_NS}}}tblPr")
    #Ensure tblBorders exists
    tbl_borders = tbl_pr.find(f'{{{WORD_NS}}}tblBorders')
    # If the table doesn't have a tblPr object (everything is set to "auto"), we create it
    if tbl_borders is None:
    tbl_borders = etree.SubElement(tbl_pr, f"{{{WORD_NS}}}tblBorders")
    if small_table:
    border_sides = ["top", "left", "bottom", "right"]
    else:
    border_sides = ["top", "left", "bottom", "right", "insideH", "insideV"]
    for side in border_sides:
    border = etree.SubElement(tbl_borders, f"{{{WORD_NS}}}{side}")
    border.set(f"{{{WORD_NS}}}val", "single")
    border.set(f"{{{WORD_NS}}}sz", "4")
    border.set(f"{{{WORD_NS}}}space", "0")
    border.set(f"{{{WORD_NS}}}color", "F07E26")
    else:
    # If there is a tblPr object, we update the color based in a map of colors
    for border in tbl_borders:
    border_color = border.attrib[f"{{{WORD_NS}}}color"]
    if (small_table and border_color != "auto") or not small_table:
    border.set(f"{{{WORD_NS}}}color", BORDER_COLOR_MAP[border.attrib[f"{{{WORD_NS}}}color"]])


    While this script works for most of the tables, I've found some tables in which it doesn't. This table for instance.

    <w:tbl 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:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:eek:="urn:schemas-microsoft-com:eek:ffice:eek:ffice" xmlns:eek:el="http://schemas.microsoft.com/office/2019/extlst" 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:eek:ffice:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" 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">\n
    <w:tblPr>\n
    <w:tblStyle w:val="Tablaconcuadrcula"/>\n
    <w:tblW w:w="9684" w:type="dxa"/>\n
    <w:jc w:val="center"/>\n
    <w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1"
    w:lastColumn="0" w:noHBand="0" w:noVBand="1"/>\n
    </w:tblPr>\n
    ....
    <w:tc>\n
    <w:tcPr>\n
    <w:tcW w:w="8062" w:type="dxa"/>\n
    <w:tcBorders>\n
    <w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>\n
    <w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>\n
    <w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>\n
    <w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>\n
    </w:tcBorders>\n
    <w:shd w:val="clear" w:color="auto" w:fill="FDE7D4"/>\n
    <w:hideMark/>\n
    </w:tcPr>\n


    I noticed that the table doesn't have a tblBorders inside of tblPr, but that every cell has the same style set individually. However I don't understand that even when I set it manually (with etree.SubElement(tbl_pr, f"{{{WORD_NS}}}tblBorders")), if I save that document, and load it again with python-docx, the properties are not there. I assume one alternative could be to edit all the cell individually with a loop, but I don't see why this doesn't work.

    Continue reading...

Compartilhe esta Página