1
votes

We typically use powerpoint to facilitate our experiments. We use "sections" in powerpoint to keep groups of slides together for each experimental task. Moving the sections to counterbalance the task order of the experiment has been a lot of work!

I thought we might be able to predefine a counterbalance order (using a string of numbers representing the order of the sections) in a CSV which could be read from python. Then using python-pptx move the sections and save the file for each order. The problem I am having is understanding how to read sections from the python-pptx. If anyone has a better solution than python please let me know.

Thanks for your help!

2
python-pptx doesn't have good functionality for rearranging/redesigning slides. I recommend you script something that generates a new powerpoint for each experiment.Reedinationer
Thanks for your reply! Can you elaborate a little? I’m sure I am making this hard.Joel Persinger

2 Answers

2
votes

As explained in the documentation (specifically this section):

Right now, adding a slide is the only operation on the slide collection. On the backlog at the time of writing is deleting a slide and moving a slide to a different position in the list. Copying a slide from one presentation to another turns out to be pretty hard to get right in the general case, so that probably won’t come until more of the backlog is burned down.

Or in other words it currently is not possible to move slides as you have suggested. The best work around I have used is to generate a new presentation and reorder the slides into this (since you can add slides).

For instance say I have slides in Presentation1.pptx of:

[0]
[1]
[2]
[3]
[4]

But I want:

[2]
[3]
[4]
[0]
[1]

Your code (in untested pseudocode of sorts) would be:

old_presentation = Presentation("Presentation1.pptx")
new_presentation = Presentation()

for slide in old_presentation.slides[2:]:
    new_slide = new_presentation.slides.add_slide() # transfer the contents into new presentation for slides [2] [3] [4]
    populate_new_slide_from_old_slide(slide, new_slide)

for slide in old_presentation.slides[:2]:
    new_slide = new_presentation.slides.add_slide() # transfer the contents into new presentation for slides [0] [1]
    populate_new_slide_from_old_slide(slide, new_slide)

new_presentation.save()

Where populate_new_slide_from_old_slide() would look like (pretty sure this would work as is, but again I didn't test it):

def populate_new_slide_from_old_slide(slide, new_slide):
    shapes_to_transfer = slide.shapes
    for shape in shapes_to_transfer:
        new_shape = new_slide.shapes.add_shape(shape)

I believe that placeholders are shapes too so they should be transferred via this method!

Take heed I haven't coded .pptx for a while, so the actual implementation might be slightly different. As a concept though, this is currently the only way to do what you're asking. In my opinion if you are actively generating the data (as opposed to just reorganizing it after the fact) it would probably be simpler to just make a new_presentation object and plug your data into that. It seems odd to me to keep generating output in the old format and then converting it to the new format. For instance, when DVDs came out people started putting their movies on that (the sensible option) instead of making VHS and then porting the VHS to DVD through some arbitrary method (the very peculiar option I am trying to dissuade you from).

0
votes

Would it be feasible - if all we're doing is reordering - to read the XML and rewrite it with the slide elements permuted?

Further - for the "delete" case - is it feasible to simply delete a slide element in the XML? (I realise this could leave dangling objects such as images in the file.)

The process of extracting the XML and rewriting it to a copy of the file is probably not too onerous.