0

I am using python-pptx library to combine two powerpoint files and everything I try constantly fails. Has anyone faced a similar issue?

I tried the following:


from pptx import Presentation
import os


prs1 = Presentation("Test1.pptx")
prs2 = Presentation("Test2.pptx")
for slide in prs2.slides:
    sl = prs1.slides.add_slide(prs1.slide_layouts[1])
    sl.shapes.title.text = slide.shapes.title.text
    sl.placeholders[1].text = slide.placeholders[1].text
prs1.save("Test3.pptx")

This fails and I keep getting errors. I also tried this:

import os
import json
import os
import numpy as np
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.util import Pt
import math
from pptx.util import Inches
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import MSO_ANCHOR, MSO_AUTO_SIZE


from pptx import Presentation

combined_presentation = Presentation()
FinancialSummaryPPT = Presentation('Test1.pptx')

for slide in FinancialSummaryPPT.slides:
    new_slide = combined_presentation.slides.add_slide(slide.slide_layout)
    for shape in slide.shapes:
        if shape.has_text_frame:
            text_frame = shape.text_frame
            new_shape = new_slide.shapes.add_textbox(shape.left, shape.top, shape.width, shape.height)
            new_text_frame = new_shape.text_frame
            new_text_frame.word_wrap = text_frame.word_wrap
            for paragraph in text_frame.paragraphs:
                new_paragraph = new_text_frame.add_paragraph()
                for run in paragraph.runs:
                    new_run = new_paragraph.add_run()
                    new_run.text = run.text
                    new_run.bold = run.bold
                    new_run.italic = run.italic
                    new_run.underline = run.underline
                    new_run.font.size = run.font.size
                    new_run.font.name = run.font.name
        elif shape.has_table:
            table = shape.table
            new_table = new_slide.shapes.add_table(rows=table.rows.__len__(), cols=table.columns.__len__(),
                                                   left=shape.left, top=shape.top,
                                                   width=shape.width, height=shape.height)
            for i in range(table.rows.__len__()):
                for j in range(table.columns.__len__()):
                    new_table.cell(i, j).text = table.cell(i, j).text

combined_presentation.save('Combined.pptx')

I get an error. Is there a better way to do this?

1 Answers1

0

There isn't really a great way to do this with python-pptx. This should cover most uses however. Full credit to this answer here on which this answer is based on - https://stackoverflow.com/a/62921781/18403743

from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
import copy

def copy_slide(slide, newpresentation):
    imgDict = {}
    layout = newpresentation.slide_masters[0].slide_layouts[6]
    slide2 = newpresentation.slides.add_slide(layout)
    group_shapes = [
        shp for shp in slide.shapes
        if shp.shape_type == MSO_SHAPE_TYPE.GROUP
        ]

    for group_shape in group_shapes:
        for shape in group_shape.shapes:
            if 'Picture' in shape.name:
                with open(shape.name+'.jpg', 'wb') as f:
                    f.write(shape.image.blob)
                imgDict[shape.name+'.jpg'] = [shape.left, shape.top, shape.width, shape.height]
            else:
                el = shape.element
                newel = copy.deepcopy(el)
                slide2.shapes._spTree.insert_element_before(newel, 'p:extLst')
               

        for k, v in imgDict.items():
            slide2.shapes.add_picture(k, v[0], v[1], v[2], v[3])
            
        for k, v in imgDict.items():
            os.remove(k)

        
    for shape in slide.shapes:
        if 'Picture' in shape.name:
            with open(shape.name+'.jpg', 'wb') as f:
                f.write(shape.image.blob)

            imgDict[shape.name+'.jpg'] = [shape.left, shape.top, shape.width, shape.height]
        else:
            el = shape.element
            newel = copy.deepcopy(el)
            slide2.shapes._spTree.insert_element_before(newel, 'p:extLst')
            


    for k, v in imgDict.items():
        slide2.shapes.add_picture(k, v[0], v[1], v[2], v[3])

    for k, v in imgDict.items():
        os.remove(k)

presentation1 = Presentation("1.pptx")
presentation2 = Presentation("2.pptx")
xml_slides = presentation2.slides._sldIdLst  
slides = list(xml_slides)
for i in range(1, len(slides)+1):
    slide = presentation2.slides[i-1]
    copy_slide(slide, presentation1)

presentation1.save("3.pptx")
Luke Bowes
  • 292
  • 2
  • 7