Skip to content

Instantly share code, notes, and snippets.

@maquedexiju
Created August 13, 2025 04:18
Show Gist options
  • Select an option

  • Save maquedexiju/adf94d8bb02083575bf57f98639d74aa to your computer and use it in GitHub Desktop.

Select an option

Save maquedexiju/adf94d8bb02083575bf57f98639d74aa to your computer and use it in GitHub Desktop.
A snippet to copy slide using python-pptx, useful when you're creating ppt in reference of a existing file.
import copy
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx import Presentation
namespaces = {
'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
'p14': 'http://schemas.microsoft.com/office/powerpoint/2010/main',
'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
}
def duplicate_slide(pres_source, pres_dest, index):
# Get the template slide to copy
template = pres_source.slides[index]
layout = template.slide_layout
# Create a new slide
copied_slide = pres_dest.slides.add_slide(layout)
# If the background is separate
if not template.follow_master_background:
copied_slide.background._element = copy.deepcopy(template.background._element)
# Process placeholders
for placeholder in template.placeholders:
o_text_frame = placeholder.text_frame._element
idx = placeholder._element.ph_idx
n_text_frame = copied_slide.placeholders[idx].text_frame._element
copied_slide.placeholders[idx]._element.replace(n_text_frame, copy.deepcopy(o_text_frame))
# Process shapes step by step
n_shps = copied_slide.shapes
for shp in template.shapes:
if shp.shape_type == MSO_SHAPE_TYPE.PLACEHOLDER:
continue
# Copy shape
el = shp.element
el_n = copy.deepcopy(el)
n_shps._spTree.insert_element_before(el_n)
n_shp = n_shps[-1]
# Process image
if shp.shape_type == MSO_SHAPE_TYPE.PICTURE:
# Copy image
_create_image_part(n_shps, n_shp, shp)
# Process images in groups
elif shp.shape_type == MSO_SHAPE_TYPE.GROUP:
_create_image_parts(n_shp.shapes, n_shp.shapes, shp.shapes)
return copied_slide
def _save_temp_img(img):
name = img.filename
dpi = img.dpi
size = img.size
blob = img.blob
content_type = img.content_type
# Save image to temporary file
with open(name, 'wb') as f:
f.write(blob)
return name
def _create_image_part(n_shps, n_shp, o_shp):
# Copy the image from o_shp to the new shapes
temp_img_file = _save_temp_img(o_shp.image)
# Save the image and generate reference id
img_part, rId = n_shps.part.get_or_add_image_part(temp_img_file)
# The reference id is in r:embed of a:blip within p:blipFill
bilp_info = n_shp._element.xpath('./p:blipFill/a:blip')[0]
# Set the new value
bilp_info.set(f'{{{namespaces['r']}}}embed', rId)
def _create_image_parts(self, n_shps, o_shps):
# Create image files
for shp in n_shps:
shp_id = shp.shape_id
o_shp = [ s for s in o_shps if s.shape_id == shp_id][0]
if shp.shape_type == MSO_SHAPE_TYPE.PICTURE:
_create_image_part(n_shps, shp, o_shp)
elif shp.shape_type == MSO_SHAPE_TYPE.GROUP:
_create_image_parts(shp.shapes, o_shp.shapes)
if __name__ == '__main__':
p = Presentation('test_origin.pptx')
pn = Presentation()
pn.slide_width = p.slide_width
pn.slide_height = p.slide_height
snn = duplicate_slide(p, pn, 0)
snn = duplicate_slide(p, pn, 1)
snn = duplicate_slide(p, pn, 2)
pn.save('test_copied.pptx')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment