Search code examples
pythonshapespython-docx

Python-docx: adding shapes (rectangle)


I want to add a shape like in the picture [example of the shape I want -- > https://i.sstatic.net/k96I2.png) to my python-docx file but cannot find a solution. It's a simple rectangle but needs to be manipulated via color, height and width and also thickness of lines and the fill.


Solution

  • The python-docx library affords the capacity to implement table borders, serving as an effective workaround for adding borders as in your image.

    Here is a full demo:

        from docx import Document
        from docx.shared import Pt
        from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
        from docx.oxml import OxmlElement
        from docx.oxml.ns import qn
        
        doc = Document()
        
        table = doc.add_table(rows=1, cols=1)
        
        table.autofit = False
        table.columns[0].width = Pt(442)
        table.rows[0].height = Pt(500) 
        
        cell = table.cell(0, 0)
        tc_pr = cell._element.get_or_add_tcPr()
        borders = OxmlElement('w:tcBorders')
        tc_pr.append(borders)
        
        for border_type in ['top', 'left', 'bottom', 'right']:
            border_elm = OxmlElement(f'w:{border_type}')
            border_elm.set(qn('w:val'), 'single')
            border_elm.set(qn('w:sz'), '24')
            border_elm.set(qn('w:space'), '0')
            border_elm.set(qn('w:color'), 'FF0000')
            borders.append(border_elm)
        
        paragraph = table.cell(0, 0).add_paragraph()
        run = paragraph.add_run('Hello, World!')
        
        paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        
        for _ in range(5):
            doc.add_paragraph()
        
        doc.save('hello_world.docx')
    

    Here you can adjust width and height:

        table.columns[0].width = Pt(442)
        table.rows[0].height = Pt(500)
    

    You can adjust the thickness of the border by changing the value of the 'w:sz' attribute. This attribute refers to the size of the border. In the XML for DOCX, the size is given in eighths of a point. So if you want a 4 point border, you would use '32' (since 4*8 = 32).

    I have to point out that I've tested this code in libre-office. Also I've added 5 empty paragraphs on the bottom, you can remove them or adjust them as needed.