Initial commit of akmon project
This commit is contained in:
128
doc_bus/generate_ppt.py
Normal file
128
doc_bus/generate_ppt.py
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
融资计划书PPT生成工具
|
||||
Convert Markdown financing plan to a PowerPoint presentation
|
||||
"""
|
||||
|
||||
import re
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
from pptx.dml.color import RGBColor
|
||||
import os
|
||||
|
||||
class PptGenerator:
|
||||
"""从Markdown生成PPT"""
|
||||
|
||||
def __init__(self, md_file, output_file='融资计划书.pptx'):
|
||||
self.md_file = md_file
|
||||
self.output_file = output_file
|
||||
self.prs = Presentation()
|
||||
self._set_slide_dimensions()
|
||||
self.content = self._read_md_file()
|
||||
|
||||
def _set_slide_dimensions(self):
|
||||
"""设置幻灯片尺寸为16:9"""
|
||||
self.prs.slide_width = Inches(16)
|
||||
self.prs.slide_height = Inches(9)
|
||||
|
||||
def _read_md_file(self):
|
||||
"""读取并解析Markdown文件"""
|
||||
with open(self.md_file, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
|
||||
def _add_title_slide(self, title, subtitle):
|
||||
"""添加标题页"""
|
||||
slide_layout = self.prs.slide_layouts[0]
|
||||
slide = self.prs.slides.add_slide(slide_layout)
|
||||
title_shape = slide.shapes.title
|
||||
subtitle_shape = slide.placeholders[1]
|
||||
title_shape.text = title
|
||||
subtitle_shape.text = subtitle
|
||||
|
||||
# 格式化
|
||||
title_shape.text_frame.paragraphs[0].font.bold = True
|
||||
title_shape.text_frame.paragraphs[0].font.size = Pt(44)
|
||||
subtitle_shape.text_frame.paragraphs[0].font.size = Pt(28)
|
||||
|
||||
def _add_content_slide(self, title, content_list, chart_path=None):
|
||||
"""添加内容页"""
|
||||
slide_layout = self.prs.slide_layouts[5] # Title Only
|
||||
slide = self.prs.slides.add_slide(slide_layout)
|
||||
|
||||
# 标题
|
||||
title_shape = slide.shapes.title
|
||||
title_shape.text = title
|
||||
title_shape.text_frame.paragraphs[0].font.size = Pt(36)
|
||||
title_shape.text_frame.paragraphs[0].font.bold = True
|
||||
|
||||
if chart_path and os.path.exists(chart_path):
|
||||
# 图文混合布局
|
||||
left = Inches(0.5)
|
||||
top = Inches(1.5)
|
||||
width = Inches(7)
|
||||
height = Inches(7)
|
||||
txBox = slide.shapes.add_textbox(left, top, width, height)
|
||||
tf = txBox.text_frame
|
||||
tf.word_wrap = True
|
||||
|
||||
img_left = Inches(8)
|
||||
img_top = Inches(1.75)
|
||||
img_width = Inches(7.5)
|
||||
slide.shapes.add_picture(chart_path, img_left, img_top, width=img_width)
|
||||
else:
|
||||
# 纯文本布局
|
||||
left = Inches(1)
|
||||
top = Inches(1.5)
|
||||
width = Inches(14)
|
||||
height = Inches(7)
|
||||
txBox = slide.shapes.add_textbox(left, top, width, height)
|
||||
tf = txBox.text_frame
|
||||
tf.word_wrap = True
|
||||
|
||||
# 添加内容
|
||||
for item in content_list:
|
||||
p = tf.add_paragraph()
|
||||
p.text = item.lstrip('-•* ').strip()
|
||||
p.level = 1 if item.strip().startswith(('•', '- ')) else 0
|
||||
p.font.size = Pt(20)
|
||||
p.alignment = PP_ALIGN.LEFT
|
||||
|
||||
def generate(self):
|
||||
"""生成PPT"""
|
||||
print(f"正在生成PPT: {self.output_file}")
|
||||
|
||||
# 提取主标题和副标题
|
||||
main_title = re.search(r'^#\s(.+)', self.content, re.MULTILINE).group(1)
|
||||
sub_title = re.search(r'^##\s(.+)', self.content, re.MULTILINE).group(1)
|
||||
self._add_title_slide(main_title, sub_title)
|
||||
|
||||
# 按章节分割
|
||||
sections = re.split(r'\n---\n', self.content)
|
||||
for section in sections:
|
||||
title_match = re.search(r'^##\s(.+)', section, re.MULTILINE)
|
||||
if not title_match:
|
||||
continue
|
||||
|
||||
title = title_match.group(1)
|
||||
|
||||
# 提取内容和图表
|
||||
content_list = re.findall(r'^\s*[-•*]\s(.+)', section, re.MULTILINE)
|
||||
chart_match = re.search(r'!\[.+?\]\((.+?)\)', section)
|
||||
chart_path = chart_match.group(1) if chart_match else None
|
||||
|
||||
if not content_list and not chart_path:
|
||||
continue
|
||||
|
||||
self._add_content_slide(title, content_list, chart_path)
|
||||
|
||||
self.prs.save(self.output_file)
|
||||
print(f"✅ PPT生成成功: {self.output_file}")
|
||||
|
||||
def main():
|
||||
generator = PptGenerator('rongzi_deepseek.md')
|
||||
generator.generate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user