使用 python-pptx 完成 ppt 页面的复制
本地首先需要 pip install python-pptx
。
在使用 python-pptx 进行页面复制时,主要需要考虑对图片文件的处理,尤其是处于分组中的图片处理
import copy
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx import Presentationnamespaces = {'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):# 获取要复制的模板幻灯片template = pres_source.slides[index]layout = template.slide_layout# 创建新幻灯片copied_slide = pres_dest.slides.add_slide(layout)# 如果背景是单独的if not template.follow_master_background:copied_slide.background._element = copy.deepcopy(template.background._element)# 再处理 placeholdersfor placeholder in template.placeholders:o_text_frame = placeholder.text_frame._elementidx = placeholder._element.ph_idxn_text_frame = copied_slide.placeholders[idx].text_frame._elementcopied_slide.placeholders[idx]._element.replace(n_text_frame, copy.deepcopy(o_text_frame))# 逐步处理形状n_shps = copied_slide.shapesfor shp in template.shapes:if shp.shape_type == MSO_SHAPE_TYPE.PLACEHOLDER:continue# 复制 shapeel = shp.elementel_n = copy.deepcopy(el)n_shps._spTree.insert_element_before(el_n)n_shp = n_shps[-1]# 处理图片if shp.shape_type == MSO_SHAPE_TYPE.PICTURE:# 复制图片_create_image_part(n_shps, n_shp, shp)# 处理分组下的图片elif shp.shape_type == MSO_SHAPE_TYPE.GROUP:_create_image_parts(n_shp.shapes, n_shp.shapes, shp.shapes)return copied_slidedef _save_temp_img(img):name = img.filenamedpi = img.dpisize = img.sizeblob = img.blobcontent_type = img.content_type# 保存图片到临时文件with open(name, 'wb') as f:f.write(blob)return namedef _create_image_part(n_shps, n_shp, o_shp):# 在新的 shapes 下,把 o_shp 中的图片复制过来temp_img_file = _save_temp_img(o_shp.image)# 把图片保存,并生成引用 idimg_part, rId = n_shps.part.get_or_add_image_part(temp_img_file)# 引用 id 在 p:blipFill 的 a:blip 中 r:embed 中bilp_info = n_shp._element.xpath('./p:blipFill/a:blip')[0]# 设置新的值bilp_info.set(f'{{{namespaces['r']}}}embed', rId)def _create_image_parts(self, n_shps, o_shps):# 创建图片文件for shp in n_shps:shp_id = shp.shape_ido_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_widthpn.slide_height = p.slide_heightsnn = duplicate_slide(p, pn, 0)snn = duplicate_slide(p, pn, 1)snn = duplicate_slide(p, pn, 2)pn.save('test_copied.pptx')