In need of help on optimizing text placement in PowerPoint table cells to prevent overflow. Instead of overflow, the goal is to position tickers in the second column, as shown in the expected output image. Shared relevant code and images for clarity. Grateful for any assistance!
Data:
Code:
import pandas as pd
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from datetime import date
# Assuming you have the small_grid DataFrame and ranking_definitions
small_grid = pd.read_excel("E:/Praveen/Technical team/WHG/WHG_process_phase_1_09272023.xlsx", sheet_name="Small_grid")
ranking_definitions = {
1: 'Bottom Fishing',
2: 'Positive Developing',
3: 'Positive Trending',
4: 'Pullback Opportunity',
5: 'Negative Developing',
6: 'Negative Trending'
}
# Create a PowerPoint presentation
presentation = Presentation()
slide = presentation.slides.add_slide(presentation.slide_layouts[6])
# Get the dimensions of the slide
slide_width = presentation.slide_width
slide_height = presentation.slide_height
# Set the margins and padding
margin_left = Inches(0.3)
margin_right = Inches(0.3)
margin_top = Inches(1.2)
margin_bottom = Inches(0.7)
# Calculate the available width and height for the table
available_width = slide_width - margin_left - margin_right
available_height = slide_height - margin_top - margin_bottom
# Determine the number of columns
num_columns = len(ranking_definitions)
# Calculate column width
column_width = available_width / num_columns
# Add a table to the slide within the specified limits
table_left = margin_left
table_top = margin_top
table_width = available_width
table_height = available_height
shape = slide.shapes.add_table(rows=2, cols=num_columns, left=table_left, top=table_top, width=table_width, height=table_height)
tbl = shape._element.graphic.graphicData.tbl
style_id = "{5940675A-B579-460E-94D1-54222C63F5DA}"
tbl[0][-1].text = style_id
table = shape.table
# Set column widths
for i in range(num_columns):
table.columns[i].width = int(column_width)
# Set header row style
header_row = table.rows[0]
header_row.height = Inches(0.7)
for i, (ranking_code, ranking_name) in enumerate(ranking_definitions.items()):
cell = header_row.cells[i] # No need to shift by 1 as there is no additional row
cell.text = ranking_name
cell.text_frame.paragraphs[0].font.size = Pt(12) # Adjust the font size for the header row
cell.text_frame.paragraphs[0].font.bold = True
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# Populate table with data
data_row = table.rows[1]
for j, (ranking_code, ranking_name) in enumerate(ranking_definitions.items()):
key = ranking_name # Adjust this line if needed
tickers = '\n'.join(small_grid[small_grid['Rankings'] == ranking_code]['Tickers'].tolist())
# Adjust the font size for data rows
cell = data_row.cells[j]
cell.text = tickers
# Set font size for each paragraph in the cell
for paragraph in cell.text_frame.paragraphs:
paragraph.font.size = Pt(10)
When using a Table with Cells this is harder than you might think. First youve to make sure that youve enough columns avaible beforhand since splitting with the pptx python package is not an option.
In my case i made 3 columns per ranking:
Then you need to merge the headers:
When populating the data youve to limit the size of a column (
size_column = 35
). Then Populate the column it with a few conditions. First checking how many tickers entries there are for a certain ranking. Later splitting does tickers into separated strings. See code below:The final touch is to remove the cell borders. The pptx python package does not have an implementation for this but there seems to be a workaround (https://github.com/scanny/python-pptx/issues/573 with Utkarsh Sinha)
Finally it looks like this:
The downsides are if you have more then 3*35 entries you will run into problems. So it would be better to build in some more restrictions etc. Also working with table/cells in pptx python seems to be pretty heinous. Maybe working with textboxes instead would be better. Those boxes to also have an autofill option.
The entire code can be found here: