2

Good day,

Python-pptx allows me to fill table cell with a color, or allows to have that cell's borders with parametrized width and color. However I can not do both, since after the fill borders disappear. I wonder how to properly combine these actions.

The desired output could look like first table from documentation: https://python-pptx.readthedocs.io/en/latest/user/table.html (the default color is blue, and this one is gray, with borders)

Minimal reproducible example:

from pptx import Presentation
from pptx.util import Cm
from pptx.oxml.xmlchemy import OxmlElement
from pptx.dml.color import ColorFormat, RGBColor

ppt = Presentation()
s1 = ppt.slide_layouts[6]
slide = ppt.slides.add_slide(s1)

rows = 3
columns = 2

shape = slide.shapes.add_table(rows, columns, left=Cm(1), top=Cm(1), width=Cm(10), height=Cm(10))
table = shape.table
table.first_row = False

#-----------------------------------------------------------------------------------------
#https://stackoverflow.com/questions/42610829/python-pptx-changing-table-style-or-adding-borders-to-cells

def SubElement(parent, tagname, **kwargs):
                element = OxmlElement(tagname)
                element.attrib.update(kwargs)
                parent.append(element)
                return element

def _set_cell_border(cell, border_color="000000", border_width='12700'):
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()
    for lines in ['a:lnR','a:lnB']:#['a:lnL','a:lnR','a:lnT','a:lnB']:
        ln = SubElement(tcPr, lines, w=border_width, cap='flat', cmpd='sng', algn='ctr')
        solidFill = SubElement(ln, 'a:solidFill')
        srgbClr = SubElement(solidFill, 'a:srgbClr', val=border_color)
        prstDash = SubElement(ln, 'a:prstDash', val='solid')
        round_ = SubElement(ln, 'a:round')
        headEnd = SubElement(ln, 'a:headEnd', type='none', w='med', len='med')
        tailEnd = SubElement(ln, 'a:tailEnd', type='none', w='med', len='med')
#-----------------------------------------------------------------------------------------
        
for r in range(rows):
    for c in range(columns):
        cell = table.cell(r,c)
        p = cell.text_frame.paragraphs[0]
        p.text = "Cell Text"
        
        #########################################################
        """
        My issue is here:
        (i) if fill.solid() and fill.fore_color(), then color, but no border
        (ii) if no solid() and no fore_color(), then border, but default blue color
        """
        
        #cell.fill.solid()
        #cell.fill.fore_color.rgb = RGBColor(100,100,100)
        _set_cell_border(cell)
        
        #########################################################
    
        
ppt.save("meeting_summary.pptx")

Post scanny comment:

def _set_cell_border(cell, border_color="000000", border_width='12700', border_list=['a:lnL','a:lnR','a:lnT','a:lnB']):
            tc = cell._tc
            tcPr = tc.get_or_add_tcPr()
            for lines in border_list:
                ln = SubElement(tcPr, lines, w=border_width, cap='flat', cmpd='sng', algn='ctr')
                solidFill = SubElement(ln, 'a:solidFill')
                schemeClr = SubElement(solidFill, 'a:schemeClr', val='bg2')
                lumMod = SubElement(schemeClr, 'a:lumMod', val="75000")
                prstDash = SubElement(ln, 'a:prstDash', val='solid')
                round_ = SubElement(ln, 'a:round')
                headEnd = SubElement(ln, 'a:headEnd', type='none', w='med', len='med')
                tailEnd = SubElement(ln, 'a:tailEnd', type='none', w='med', len='med')
            solidFill = SubElement(tcPr, 'a:solidFill')
            schemeClr = SubElement(solidFill, 'a:schemeClr', val='bg1')

A different interpretation of cell fill and border coloring. You could even pass only few borders to create something like 'all borders except most outer one' shape. Edit 'val' for variations.

One example: enter image description here

Dan_Banan
  • 21
  • 5
  • Hi Dan. Welcome to StackOverflow. Please take a look at: https://stackoverflow.com/help/minimal-reproducible-example. Please show us your code. This way you may make it easier for someone to anwer your question. You could speed up getting an answer. – greenmarker Nov 30 '20 at 12:08
  • 1
    Hello @greenmarker, and thank you for a tip – Dan_Banan Nov 30 '20 at 12:47
  • @Dan a good place to start the diagnosis is by creating an example of the desired state (fill + border) with PowerPoint and then inspecting the XML it generates. The challenge is then for your code to generate that same XML (or at least the parts that make it work). You can print the XML for a cell with `cell._tc.xml`. Then you should be able to narrow down what is getting written (or overwritten) in the wrong place. – scanny Nov 30 '20 at 17:28
  • @scanny - your suggestion was an eye opener, thank you very much – Dan_Banan Dec 01 '20 at 14:29

0 Answers0