fin-ppt / ppt_handler.py
luofengge's picture
Upload folder using huggingface_hub
e9f9eab verified
Raw History Blame Contribute Delete
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