Files
akmon/doc_bus/generate_ppt.py
2026-01-20 08:04:15 +08:00

129 lines
4.3 KiB
Python

#!/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()