Download ppt_handler.py from luofengge/fin-ppt: direct link, hf CLI and curl.
- Browser
- Download file 8.53 kB
-
https://huggingface.co/spaces/luofengge/fin-ppt/resolve/main/ppt_handler.py
- Command line
-
hf download hf://spaces/luofengge/fin-ppt/ppt_handler.py
-
curl -L -o ppt_handler.py https://huggingface.co/spaces/luofengge/fin-ppt/resolve/main/ppt_handler.py
8.53 kB
| 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 | |