from pptx import Presentation from pptx.slide import Slide from typing import List import os,json from pptx.util import Inches, Pt,Cm from pptx.dml.color import RGBColor from pptx.text.text import Font import structure import six,copy import random from img_search import get_img class PPTHandler(): # 主题文件位置 theme: str = "1" theme_path : str = "./theme/" prs: Presentation = None content:dict = {} def __init__(self,structure,theme,**kwargs): self.structure = structure self.prs = Presentation(self.theme_path+f"{theme}/template.pptx") # 初始化一个主题对象 # with open(self.theme_param_path,encoding="utf-8") as f: # self.theme_param = json.load(f) # 生成封面 def run(self): try: yield "检索插图" self.img_dicts = get_img(self.structure.title) # self.img_dicts = ddg_images(keywords, region='wt-wt', safesearch='Off', size=None,color='Monochrome', type_image=None, layout=None, license_image=None, max_results=300) print("一共检索到的图片数量为",len(self.img_dicts)) print(self.img_dicts) except: self.img_dicts=[] yield "生成封面" self.gen_cover() yield "生成目录" self.gen_index() yield "生成内容页" for msg in self.gen_content(): yield msg print("生成结尾") self.gen_end() print("删除模板") self.delete_template() yield "生成文件" print("生成文件") self.prs.save(f"{self.structure.title}.pptx") def gen_cover_list(self): # 生成封面列表 pass def gen_cover(self): print("生成封面") # 替换标题 print(self.structure) cover_slide = self.copy_slide(self.find_temp_slide("template:cover")) self.replace_text(cover_slide, "title", self.structure.title) cover_slide.notes_slide.notes_text_frame.text = "FIN-PPT生成" # 增加一页 def gen_index(self): print("生成索引") print(self.structure.structure) index_slide = self.copy_slide(self.find_temp_slide("template:index")) for idx,stru in enumerate(self.structure.structure): print(stru['main_idea']) self.replace_text(index_slide, f"main_idea_{idx+1}", stru['main_idea']) index_slide.notes_slide.notes_text_frame.text = "FIN-PPT生成" # 增加一页 self.delete_shapes_with_text(index_slide,"main_idea") # print(self.structure.structure) def gen_content(self): print("生成内容") for idx,stru in enumerate(self.structure.structure): print(f"生成:{stru['main_idea']}") sub_title_slide = self.copy_slide(self.find_temp_slide("template:subtitle")) self.replace_text(sub_title_slide, f"index", f"{idx+1}") self.replace_text(sub_title_slide, f"main_idea", stru['main_idea']) for idx,sub_idea in enumerate(stru['sub_idea']): print(f"生成子内容页面:{sub_idea}") point_titles = self.structure.get_point_title(sub_idea = sub_idea,r_num = random.randint(2, 6)) # print(f"长度:{len(point_titles)}") len_p = len(point_titles) content_slide = self.copy_slide(self.find_temp_slide(f"template:{len_p}_content_1")) self.replace_text(content_slide, f"sub_idea", sub_idea) yield f"思考主题:{sub_idea}" print("生成内容:") for idx,point_title in enumerate(point_titles): point_content = self.structure.get_point_content(point_title) print(point_content) # 开始搞slider了! yield f"撰写内容:{point_content}" self.replace_text(content_slide, f"point_title_{idx+1}", point_title) self.replace_text(content_slide, f"point_content_{idx+1}", point_content) if len(self.img_dicts) > 0: yield f"插入插图" self.insert_pic(content_slide,f"point_img") content_slide.notes_slide.notes_text_frame.text = "FIN-PPT生成" sub_title_slide.notes_slide.notes_text_frame.text = "FIN-PPT生成" self.delete_files() # 增加一页 def gen_end(self): print("生成结束") # 替换标题 end_slide = self.copy_slide(self.find_temp_slide("template:end")) # self.replace_text(end_slide, "title", self.structure.title) end_slide.notes_slide.notes_text_frame.text = "FIN-PPT生成" def delete_template(self): # for slide in self.prs.slides: # if "template" in slide.notes_slide.notes_text_frame.text : # print("删除模板页") # self.prs.slides._sldIdLst.remove(slide) xml_slides = self.prs.slides._sldIdLst slides = list(xml_slides) for i in range(len(slides),0,-1): slide = self.prs.slides[i-1] if "template" in slide.notes_slide.notes_text_frame.text : xml_slides.remove(slides[i-1]) def give_temp_tag(self): for slide in self.prs.slides: slide.note = 'is_temple' def replace_text(self,slide, placeholder, new_text): for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: for run in paragraph.runs: if placeholder in run.text: run.text = run.text.replace(placeholder, new_text) def insert_pic(self,slide, placeholder): for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: for run in paragraph.runs: if placeholder in run.text: run.text = "" img_path = self.img_dicts[random.randint(0, len(self.img_dicts) - 1)]['path'] print(f":插入图片:{img_path}") slide.shapes.add_picture(img_path, shape.left, shape.top,shape.width, shape.height) slide.shapes._spTree.remove(shape._element) def delete_files(self): for path in self.img_dicts: if os.path.exists(path['path']): try: os.remove(path['path']) print(f"File {path['path']} deleted successfully.") except OSError as e: print(f"Error deleting file {path['path']}: {e}") def find_temp_slide(self,name): for slide in self.prs.slides: if name in slide.notes_slide.notes_text_frame.text : return slide def delete_shapes_with_text(self,slide, text): shapes_to_delete = [] for shape in slide.shapes: if shape.has_text_frame: if text in shape.text: shapes_to_delete.append(shape) for shape in shapes_to_delete: slide.shapes._spTree.remove(shape._element) def copy_slide(self,slide_to_copy): pres = self.prs try: blank_slide_layout = pres.slide_layouts[12] except: blank_slide_layout = pres.slide_layouts[len(pres.slide_layouts)-1] copied_slide = pres.slides.add_slide(blank_slide_layout) for shp in slide_to_copy.shapes: if shp.shape_type == 13: # 判断是否为图片(shape_type为13) with open(shp.name+'.jpg', 'wb') as f: f.write(shp.image.blob) copied_slide.shapes.add_picture(shp.name+'.jpg', shp.left, shp.top,shp.width, shp.height) continue el = shp.element newel = copy.deepcopy(el) copied_slide.shapes._spTree.insert_element_before(newel, 'p:extLst') # 删除所有placeholder shapes = copied_slide.shapes for shape in shapes: if shape.is_placeholder: copied_slide.shapes._spTree.remove(shape._element) return copied_slide