from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
pr = Presentation('周彤.pptx')
for slide in pr.slides:
for shape in slide.shapes:
if shape.shape_type==MSO_SHAPE_TYPE.TEXT_BOX:
print(shape.text_frame.font.name,end='\n\n')
#shape.has_text_frame 判断是否为文本框形状
from pptx import Presentation
from pptx.util import Inches, Cm
from pptx.enum.shapes import MSO_SHAPE_TYPE
import io
from pptx.dml.color import RGBColor
from pptx.util import Pt
import re
def load_template(ppt_template_path):
""" 加载模板 PPT """
prs = Presentation(ppt_template_path)
return prs
def copy_slide_layout(prs, idx):
""" 复制模板中的幻灯片布局 """
slide_layout = prs.slide_layouts[idx]
return slide_layout
def create_slide_from_layout(prs, slide_layout, content, images):
""" 使用布局创建新幻灯片,填充内容和图片,并添加姓名文本框 """
slide = prs.slides.add_slide(slide_layout)
if 'title' in content and 'body' in content:
title = slide.shapes.title
body = slide.placeholders[1] if len(slide.placeholders) > 1 else None
if title:
title.text = content['title']
if body:
tf = body.text_frame
tf.text = content['body']
# 添加图片
left = top = Inches(1)
for image in images:
slide.shapes.add_picture(image, left, top, width=Inches(2))
left += Inches(2.5) # 调整下一张图片的位置
# 移除姓名文本框的添加,因为这个功能在 adjust_text_format_and_position 中已经实现
return slide
def merge_ppts(template_path, single_page_ppts, output_path):
""" 合并多个单页 PPT 到模板中,包括图片,并输出结果 """
prs = load_template(template_path)
# 获取第一个布局作为标准格式
standard_layout = prs.slide_layouts[0]
for ppt in single_page_ppts:
single_prs = Presentation(ppt)
if len(single_prs.slides) > 0:
content = {'title': '', 'body': '', 'name': ''}
images = []
slide = single_prs.slides[0]
title_shape = slide.shapes.title
if title_shape:
content['title'] = title_shape.text
# 假设标题就是姓名
content['name'] = title_shape.text
for shape in slide.shapes:
if shape.has_text_frame:
content['body'] += shape.text_frame.text + "\n"
elif shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
# 提取图片
image = shape.image
image_bytes = image.blob
images.append(io.BytesIO(image_bytes))
# 使用标准布局创建新幻灯片,包括图片
new_slide = create_slide_from_layout(prs, standard_layout, content, images)
# 调整文本框格式和位置
extracted_name = adjust_text_format_and_position(new_slide)
# 调整图片位置和大小
image_shape = adjust_image_position_and_size(new_slide)
# 如果有图片,再次调整名字文本框的位置
if image_shape:
adjust_name_position(new_slide, image_shape, extracted_name)
prs.save(output_path)
print(f"合并的幻灯片(包括图片)已保存到 {output_path}")
def adjust_text_format_and_position(slide):
""" 调整幻灯片文本框格式和位置,并提取姓名 """
max_text_shape = None
max_text_length = 0
extracted_name = "" # 默认为空字符串
for shape in slide.shapes:
if shape.has_text_frame:
text_length = len(shape.text_frame.text)
if text_length > max_text_length:
max_text_length = text_length
max_text_shape = shape
if max_text_shape:
# 尝试从文本中提取姓名
text = max_text_shape.text_frame.text
name_match = re.search(r'([\u4e00-\u9fa5]{2,4})', text)
if name_match:
extracted_name = name_match.group(1)
# 设置最大文本框的格式和位置
max_text_shape.width = Cm(23.26)
max_text_shape.height = Cm(13.57)
max_text_shape.left = Cm(9.81)
max_text_shape.top = Cm(4.31)
# 设置文本格式
text_frame = max_text_shape.text_frame
for paragraph in text_frame.paragraphs:
paragraph.alignment = 1 # 1 表示左对齐
for run in paragraph.runs:
run.font.name = '微软雅黑'
run.font.size = Pt(16)
run.font.color.rgb = RGBColor(255, 255, 255) # 白色
return extracted_name
def adjust_name_position(slide, image_shape, extracted_name):
""" 调整姓名文本框的位置和样式 """
name_box = None
for shape in slide.shapes:
if shape.has_text_frame and shape.text_frame.text == extracted_name:
name_box = shape
break
if not name_box and extracted_name:
name_box = slide.shapes.add_textbox(Cm(2.04), Cm(12.61), Cm(5), Cm(1))
if name_box and extracted_name:
# 使用 round() 函数将浮点数转换为整数
name_box.left = round(image_shape.left + (image_shape.width - name_box.width) / 2)
name_box.top = round(image_shape.top + image_shape.height + Cm(0.5))
name_frame = name_box.text_frame
name_frame.text = extracted_name
name_frame.paragraphs[0].alignment = 1 # 居中对齐
name_frame.paragraphs[0].font.name = '微软雅黑'
name_frame.paragraphs[0].font.size = Pt(16)
name_frame.paragraphs[0].font.bold = True
name_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255)
if len(extracted_name) == 2:
name_frame.paragraphs[0].runs[0].font.char_spacing = Pt(16)
def adjust_image_position_and_size(slide):
""" 调整图片位置和大小 """
image_shape = None
for shape in slide.shapes:
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
shape.left = Cm(3.23)
shape.top = Cm(4.46)
shape.width = Cm(5.54)
shape.height = Cm(7.79)
image_shape = shape
break # 只调整第一张图片
return image_shape
示例调用
template_path = '1.pptx'
single_page_ppts = ['simple.pptx', 'simple1.pptx']
output_path = 'merged_output.pptx'
merge_ppts(template_path, single_page_ppts, output_path)