Python-PPTX: Changing table style or adding borders to cells

JJFord3 picture JJFord3 · Mar 5, 2017 · Viewed 7.2k times · Source

I've started putting together some code to take Pandas data and put it into a PowerPoint slide. The template I'm using defaults to Medium Style 2 - Accent 1 which would be fine as changing the font and background are fairly easy, but there doesn't appear to be an implemented portion to python-pptx that allows for changing cell borders. Below is my code, open to any solution. (Altering the XML or changing the template default to populate a better style would be good options for me, but haven't found good documentation on how to do either). Medium Style 4 would be ideal for me as it has exactly the borders I'm looking for.

import pandas
import numpy
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor

#Template Location
tmplLoc = 'C:/Desktop/'

#Read in Template
prs = Presentation(tmplLoc+'Template.pptx')

#Import data as Pandas Dataframe - dummy data for now
df = pandas.DataFrame(numpy.random.randn(10,10),columns=list('ABCDEFGHIJ'))

#Determine Table Header
header = list(df.columns.values)

#Determine rows and columns
in_rows = df.shape[0]
in_cols = df.shape[1]

#Insert table from C1 template
slide_layout = prs.slide_layouts[11]
slide = prs.slides.add_slide(slide_layout)

#Set slide title
title_placeholder = slide.shapes.title
title_placeholder.text = "Slide Title"

#Augment placeholder to be a table
placeholder = slide.placeholders[1]
graphic_frame = placeholder.insert_table(rows = in_rows+1, cols = in_cols)
table = graphic_frame.table
#table.apply_style = 'MediumStyle4'
#table.apply_style = 'D7AC3CCA-C797-4891-BE02-D94E43425B78'

#Set column widths
table.columns[0].width = Inches(2.23)
table.columns[1].width = Inches(0.9)
table.columns[2].width = Inches(0.6)
table.columns[3].width = Inches(2)
table.columns[4].width = Inches(0.6)
table.columns[5].width = Inches(0.6)
table.columns[6].width = Inches(0.6)
table.columns[7].width = Inches(0.6)
table.columns[8].width = Inches(0.6)
table.columns[9].width = Inches(0.6)
#total_width = 2.23+0.9+0.6+2+0.6*6

#Insert data into table
for rows in xrange(in_rows+1):
    for cols in xrange(in_cols):
        #Write column titles
        if rows == 0:
            table.cell(rows, cols).text = header[cols]
            table.cell(rows, cols).text_frame.paragraphs[0].font.size=Pt(14)
            table.cell(rows, cols).text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255)
            table.cell(rows, cols).fill.solid()
            table.cell(rows, cols).fill.fore_color.rgb=RGBColor(0, 58, 111) 
        #Write rest of table entries
        else:
            table.cell(rows, cols).text = str("{0:.2f}".format(df.iloc[rows-1,cols]))
            table.cell(rows, cols).text_frame.paragraphs[0].font.size=Pt(10)
            table.cell(rows, cols).text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0)
            table.cell(rows, cols).fill.solid()
            table.cell(rows, cols).fill.fore_color.rgb=RGBColor(255, 255, 255)

#Write Table to File
prs.save('C:/Desktop/test.pptx')

Answer

JuuLes87 picture JuuLes87 · Jan 17, 2018

Maybe not really clean code but allowed me to adjust all borders of all cells in a table:

from pptx.oxml.xmlchemy import OxmlElement

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: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')

Based on this post: https://groups.google.com/forum/#!topic/python-pptx/UTkdemIZICw