from pptx.enum.text import PP_ALIGN
from pptx.util import Inches, Mm, Pt, Emu
from pptx.enum.dml import MSO_FILL_TYPE
from pptx.oxml.xmlchemy import OxmlElement
from datetime import date
import pandas as pd
import numpy as np
#region Read in the Template and load it
path = "Template/Template.pptx"
prs = Presentation(path)
#endregion
#region Functions
def SubElement(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def _set_cell_border(cell, border_color="FFFFFF", border_width='12700'):
""" Hack function to enable the setting of border width and border color
- bottom border only at present
(c) Steve Canny
"""
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
lnB = SubElement(tcPr, 'a:lnB', w=border_width, cap='flat', cmpd='sng', algn='ctr')
solidFill = SubElement(lnB, 'a:NoFill')
#endregion
#region Dataframe
df = pd.DataFrame()
df["name"] = ["Nick","Gaetano", "George", "Jason","Death", "God", 'Stan', "Satan","Beel","Nick","Gaetano", "George", "Jason","Death", "God", 'Stan', "Satan","Beel"]
df["Restaurant Manager"] = ["Sam","Mason", "Sam", "Mason","Mason","Sam","Sam","Sam","Mason","Sam","Mason", "Sam", "Mason","Mason","Sam","Sam","Sam","Mason"]
df["Score"] = np.random.randint(5,30,size=18)
df['Percentile Rank'] = np.random.randint(5,101,size=18)
df["Restaurant Name"] = ["Elise","Bob","Death","Elise","Bob","Death","Elise","Bob","Death","Elise","Bob","Death","Elise","Bob","Death","Elise","Bob","Death"]
df = df[df.groupby(['Restaurant Name', 'Restaurant Manager']).cumcount() < 3]
#endregion
#region Get layout info
#slide = prs.slides.add_slide(prs.slide_layouts[3])
#for shape in slide.placeholders:
# print('%d %s' % (shape.placeholder_format.idx, shape.name))
#endregion
#region Slide #3 Table
slide_layout = prs.slide_layouts[3]
slide = prs.slides.add_slide(slide_layout)
placeholder = slide.placeholders[0]
placeholder.text = "Restaurant TABLE Analysis"
table_placeholder = slide.shapes[1]
shape = table_placeholder.insert_table(rows=13, cols=14)
table = shape.table
#endregion
#region Setting Table Parameters
# Setting the backfround colour to invsible for the rows
for row in table.rows:
for cell in row.cells:
for paragraph in cell.text_frame.paragraphs:
paragraph.font.size = Pt(1) # set font size to 1
rownumbers= [1,7]
colnumbers = [4,9]
for i in rownumbers:
row = table.rows[i] # select row
for cell in row.cells:
cell.text_frame.paragraphs[0].font.size = Pt(1) # set font size to 1 pt
cell.fill.background() # set background to be transparent
row.height = Mm(2) # set height
# Setting the backfround colour to invsible for the columns
for i in colnumbers:
column = table.columns[i] # select column
column_index = i
for row in table.rows:
cell = row.cells[column_index]
cell.text_frame.paragraphs[0].font.size = Pt(1) # set font size to 1 pt
cell.fill.background() # set background to be transparent
column.width = Mm(2) # set width
# Merging the cells in the rows
for row_index in rownumbers:
first_cell_index = 0 # index of the first cell in the row
last_cell_index = len(table.columns) - 1 # index of the last cell in the row
row = table.rows[row_index]
first_cell = row.cells[first_cell_index]
last_cell = row.cells[last_cell_index]
first_cell.merge(last_cell) # merge the cells
#endregion
#region Creating Tables
# Group the data by the 'Restaurant Name' column
groups = df.groupby('Restaurant Name')
# Set the starting index
i = 0
# Iterate through the groups
for name, group in groups:
# Insert the group name (i.e. the restaurant name) into the first cell
cell = table.cell(0, i)
cell.text = name
cell.text_frame.paragraphs[0].font.size = Pt(18)
# cell.text_frame.paragraphs[0].font.name = 'Arial' # font style
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
cell3 = table.cell(0, i+3)
cell.merge(cell3)
# Group the data in the current group by the 'Restaurant Manager' column
df_manager_grouped = group.groupby('Restaurant Manager')
i_2 = 2
# Iterate through the subgroups
for manager_name, manager_group in df_manager_grouped:
# Insert the group name (i.e. the restaurant manager name) into the second cell
cell = table.cell(i_2, i)
cell.text = manager_name
cell.text_frame.paragraphs[0].font.size = Pt(12)
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
cell3 = table.cell(i_2,i+3)
cell.merge(cell3)
# Insert the remaining data for the current subgroup
# Set the row index
row_index = i_2 + 2
for index in range(len(manager_group)):
# Insert the data into the cells
cell = table.cell(row_index, i)
cell.text = str(index + 1)
cell.text_frame.paragraphs[0].font.size = Pt(12)
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
cell = table.cell(row_index, i + 1)
cell.text = manager_group.iloc[index]['name']
cell.text_frame.paragraphs[0].font.size = Pt(12)
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.LEFT
cell = table.cell(row_index, i + 2)
cell.text = str(manager_group.iloc[index]['Score'])
cell.text_frame.paragraphs[0].font.size = Pt(12)
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
cell = table.cell(row_index, i + 3)
cell.text = str(manager_group.iloc[index]['Percentile Rank'])
cell.text_frame.paragraphs[0].font.size = Pt(12)
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# Increment the row index
row_index += 1
i_2 += 6
# Increment the index
i += 5
# center the table horizontally and vertically
slide_width = prs.slide_width
table_width = shape.width
shape.left = round((slide_width - table_width) / 2)
cell = table.cell(6,4)
_set_cell_border(cell)
#endregion
prs.save('test.pptx')
As the title states, I want to remove the borders of a specific cell but for some reason my code is unable to do so. I have attempted the proposed solutions found here (Python-PPTX: Changing table style or adding borders to cells) but no matter what I do, I am unable to do so.
Preferably I would like to be able to specify which border I want to remove (i.e. Remove only the top.. or remove both top and bottom) but I think I will be able to figure it out once I know how to remove all the borders.
Any help would be much appreciated.