0

I want to automate the creation of PowerPoint slides with one certificate per student per slide. To do this I take the student names from an excel spreadsheet and put them in an existing PowerPoint. I have, for example, 100 students and therefore, I need 100 different certificates in my PowerPoint. Here's what I've done so far:

from pptx import Presentation
import pandas as pd

dataframe = pd.read_excel('normal.xlsx')



prs = Presentation('C:\\Users\\xyz\\Desktop\\demo.pptx')

repl_str_u = 'Jhon cena'
repl_str_y = 'Dec-2019'
repl_str_l = 'Tom curze'

users = []
for i in dataframe['Nominee Name']:
    users.append(i)

x = len(users)

Manager = []
for i in dataframe['LPM']:
    Manager.append(i)

Month = []
for i in dataframe['Period']:
    Month.append(i)

for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            for i in range(x):
                shape.text = shape.text.replace(search_str_username, users[i])
                shape.text = shape.text.replace(search_str_formonth, Month[i])
                shape.text = shape.text.replace(search_str_lpm, Manager[i])


prs.save('C:\\Users\\suraj\\Desktop\\op.pptx') 
Joseph Chotard
  • 666
  • 5
  • 15

1 Answers1

0

I made this example using a template (demo.pptx) with only 3 text boxes. The result is a presentation with 10 slides, each one with different texts. I used a function to duplicate slides that I found in this post. It could be several changes to make in your use case, but this is the general idea.

from pptx import Presentation
import pandas as pd
import copy
import six

def duplicate_slide(pres,index):
    template = pres.slides[index]
    try:
        blank_slide_layout = pres.slide_layouts[6]
    except:
        blank_slide_layout = pres.slide_layouts[len(pres.slide_layouts)-1]

    copied_slide = pres.slides.add_slide(blank_slide_layout)

    for shp in template.shapes:
        el = shp.element
        newel = copy.deepcopy(el)
        copied_slide.shapes._spTree.insert_element_before(newel, 'p:extLst')

    for _, value in six.iteritems(template.part.rels):
        # Make sure we don't copy a notesSlide relation as that won't exist
        if "notesSlide" not in value.reltype:
            copied_slide.part.rels.add_relationship(value.reltype,
                                            value._target,
                                            value.rId)

    return copied_slide

data = {'user': ['U0', 'U1', 'U2', 'U3', 'U4', 'U5', 'U6', 'U7', 'U8', 'U9'],
        'Manager': ['M0', 'M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9'],
        'Month': ['D0', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9']}

df = pd.DataFrame(data)

prs = Presentation('demo.pptx')
x = df.shape[0]

for u in range(x-1):
    copied_slide = duplicate_slide(prs, 0)

for i, slide in enumerate(prs.slides):
    for j, shape in enumerate(slide.shapes):
        if shape.has_text_frame:
            shape.text = df.iloc[i, j]

prs.save('op.pptx')

This is how it looks "demo.pptx": enter image description here

jjsantoso
  • 1,586
  • 1
  • 12
  • 17