[英]Python-pptx: copy slide
如何復制幻燈片?
我創建了一個模板幻燈片,我需要復制它並分別編輯每個副本的形狀。
或者如何將模板幻燈片添加到 presentation.slide_layouts?
這是我在 GitHub 上找到的,它對我有用。 我確實為我的項目更改了一些東西。 您將需要導入六個並復制。 我正在使用 pptx-6.10
def duplicate_slide(pres, index):
template = pres.slides[index]
try:
blank_slide_layout = pres.slide_layouts[12]
except:
blank_slide_layout = pres.slide_layouts[len(pres.slide_layouts)]
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
然后,您可以通過傳入演示文稿和模板的幻燈片索引來創建副本:
copied_slide = duplicate_slide(pres, 4)
我仍在編輯復制的幻燈片中的形狀,一旦我在我的項目中進一步發展,我就可以更新
我想展示我復制幻燈片的解決方法。 我使用模板ppt並填充它。 在填充幻燈片之前,我知道需要復制模板的哪些幻燈片以及復制頻率。 然后我要做的是復制幻燈片並用復制的幻燈片保存新的ppt。 保存后,我可以使用復制的幻燈片打開 ppt 並使用 pptx 填充幻燈片。
import win32com.client
ppt_instance = win32com.client.Dispatch('PowerPoint.Application')
#open the powerpoint presentation headless in background
read_only = True
has_title = False
window = False
prs = ppt_instance.Presentations.open('path/ppt.pptx',read_only,has_title,window)
nr_slide = 1
insert_index = 1
prs.Slides(nr_slide).Copy()
prs.Slides.Paste(Index=insert_index)
prs.SaveAs('path/new_ppt.pptx')
prs.Close()
#kills ppt_instance
ppt_instance.Quit()
del ppt_instance
在這種情況下,第一張幻燈片將復制演示文稿並插入到同一演示文稿的第一張幻燈片之后。
希望這對你們中的一些人有所幫助!
我正在使用n00by0815 的答案,並且在我不得不復制圖像之前效果很好。 這是我處理圖像的改編版本。 此代碼創建圖像的本地副本,然后將其添加到幻燈片中。 我確定有一種更清潔的方法,但這是有效的。
由於我還找到了@d_bergeron 共享代碼的另一個用例,所以我只想在這里分享。 就我而言,我想將另一個演示文稿中的幻燈片復制到我使用 python-pptx 生成的幻燈片中:
作為參數,我傳入了我使用 python-pptx (prs = Presenation()) 創建的 Presentation() 對象。
from pptx import Presentation
import copy
def copy_slide_from_external_prs(prs):
# copy from external presentation all objects into the existing presentation
external_pres = Presentation("PATH/TO/PRES/TO/IMPORT/from.pptx")
# specify the slide you want to copy the contents from
ext_slide = external_pres.slides[0]
# Define the layout you want to use from your generated pptx
SLD_LAYOUT = 5
slide_layout = prs.slide_layouts[SLD_LAYOUT]
# create now slide, to copy contents to
curr_slide = prs.slides.add_slide(slide_layout)
# now copy contents from external slide, but do not copy slide properties
# e.g. slide layouts, etc., because these would produce errors, as diplicate
# entries might be generated
for shp in ext_slide.shapes:
el = shp.element
newel = copy.deepcopy(el)
curr_slide.shapes._spTree.insert_element_before(newel, 'p:extLst')
return prs
我主要在這里發布它,因為我一直在尋找一種方法將外部幻燈片復制到我的演示文稿中,並最終出現在這個線程中。
我編輯了@n00by0815 解決方案並提出了非常優雅的代碼,它也可以無誤地復制圖像:
# ATTENTNION: PPTX PACKAGE RUNS ONLY ON CERTAINS VERSION OF PYTHON (https://python-pptx.readthedocs.io/en/latest/user/install.html)
from pptx import Presentation
from pptx.util import Pt
from pptx.enum.text import PP_ALIGN
import copy
import os
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
#modeled on https://stackoverflow.com/a/56074651/20159015 and https://stackoverflow.com/a/62921848/20159015
#this for some reason doesnt copy text properties (font size, alignment etc.)
def SlideCopyFromPasteInto(copyFromPres, slideIndex, pasteIntoPres):
# specify the slide you want to copy the contents from
slide_to_copy = copyFromPres.slides[slideIndex]
# Define the layout you want to use from your generated pptx
slide_layout = pasteIntoPres.slide_layouts.get_by_name("Blank") # names of layouts can be found here under step 3: https://www.geeksforgeeks.org/how-to-change-slide-layout-in-ms-powerpoint/
# it is important for slide_layout to be blank since you dont want these "Write your title here" or something like that textboxes
# alternative: slide_layout = pasteIntoPres.slide_layouts[copyFromPres.slide_layouts.index(slide_to_copy.slide_layout)]
# create now slide, to copy contents to
new_slide = pasteIntoPres.slides.add_slide(slide_layout)
# create images dict
imgDict = {}
# now copy contents from external slide, but do not copy slide properties
# e.g. slide layouts, etc., because these would produce errors, as diplicate
# entries might be generated
for shp in slide_to_copy.shapes:
if 'Picture' in shp.name:
# save image
with open(shp.name+'.jpg', 'wb') as f:
f.write(shp.image.blob)
# add image to dict
imgDict[shp.name+'.jpg'] = [shp.left, shp.top, shp.width, shp.height]
else:
# create copy of elem
el = shp.element
newel = copy.deepcopy(el)
# add elem to shape tree
new_slide.shapes._spTree.insert_element_before(newel, 'p:extLst')
# things added first will be covered by things added last => since I want pictures to be in foreground, I will add them after others elements
# you can change this if you want
# add pictures
for k, v in imgDict.items():
new_slide.shapes.add_picture(k, v[0], v[1], v[2], v[3])
os.remove(k)
return new_slide # this returns slide so you can instantly work with it when it is pasted in presentation
templatePres = Presentation(f"{DIR_PATH}/template.pptx")
outputPres = Presentation()
outputPres.slide_height, outputPres.slide_width = templatePres.slide_height, templatePres.slide_width
# this can sometimes cause problems. Alternative:
# outputPres = Presentation(f"{DIR_PATH}/template.pptx") and now delete all slides to have empty presentation
# if you just want to copy and paste slide:
SlideCopyFromPasteInto(templatePres,0,outputPres)
# if you want to edit slide that was just pasted in presentation:
pastedSlide = SlideCopyFromPasteInto(templatePres,0,outputPres)
pastedSlide.shapes.title.text = "My very cool title"
for shape in pastedSlide.shapes:
if not(shape.has_text_frame): continue
# easiest ways to edit text fields is to put some identifying text in them
if shape.text_frame.text == "personName": # there is a text field with "personName" written into it
shape.text_frame.text = "Brian"
if shape.text_frame.text == "personSalary":
shape.text_frame.text = str(brianSalary)
# stylizing text need to be done after you change it
shape.text_frame.paragraphs[0].font.size = Pt(80)
shape.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
outputPres.save(f'{DIR_PATH}/output.pptx')
抱歉耽擱了,我被轉移到另一個項目。 我能夠使用多個模板幻燈片並復制它們來完成我的 ppt 項目。 在構建演示文稿的最后,我刪除了模板。 要抓取形狀,您需要遍歷 slide.shapes 並找到您要查找的形狀的名稱。 返回后,您可以根據需要編輯形狀。 我添加了一個用於填充 shape.text_frame 的 add_text 函數版本。
def find_shape_by_name(shapes, name):
for shape in shapes:
if shape.name == name:
return shape
return None
def add_text(shape, text, alignment=None):
if alignment:
shape.vertical_anchor = alignment
tf = shape.text_frame
tf.clear()
run = tf.paragraphs[0].add_run()
run.text = text if text else ''
找到形狀“slide_title”。
slide_title = find_shape_by_name(slide.shapes,'slide_title')
向形狀添加文本。
add_text(slide_title,'TEST SLIDE')
如果您需要任何其他幫助,請告訴我。
這是將每張幻燈片復制到單個 PPTX 幻燈片以用於整個演示文稿的另一種方法,然后您可以使用 LibreOffice 將每個單獨的 powerpoint 轉換為圖像:
def get_slide_count(prs):
""" Get the number of slides in PPTX presentation """
slidecount = 0
for slide in prs.slides:
slidecount += 1
return slidecount
def delete_slide(prs, slide):
""" Delete a slide out of a powerpoint presentation"""
id_dict = { slide.id: [i, slide.rId] for i,slide in enumerate(prs.slides._sldIdLst) }
slide_id = slide.slide_id
prs.part.drop_rel(id_dict[slide_id][1])
del prs.slides._sldIdLst[id_dict[slide_id][0]]
def get_single_slide_pres(prs, slidetokeep):
for idx, slide in enumerate(prs.slides):
if idx < slidetokeep:
delete_slide(prs, slide)
elif (idx > slidetokeep):
delete_slide(prs, slide)
prs.save(str(slidetokeep + 1) + ".pptx")
pptxfilepath = "test.pptx"
prs = Presentation(pptxfilepath)
slidecount = get_slide_count(prs)
for i in range(slidecount):
prs_backup = Presentation(pptxfilepath)
get_single_slide_pres(prs_backup, i)
prs_backup = None
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.