def generate_ppts_from_excel(excel_path, template_path, output_dir,flag): """主生成函数""" os.makedirs(output_dir, exist_ok=True) try: # 设置显示选项 pd.set_option('display.max_rows', None) pd.set_option('display.max_columns', None) # 读取数据,默认读取第一sheet页 df = pd.read_excel(excel_path, header=None) # 处理表头 header_row1 = df.iloc[0].fillna(method='ffill') header_row2 = df.iloc[1] #new_columns2 = [f"{h1}-{h2}" for h1, h2 in zip(header_row1, header_row2)] new_columns = [f"{h2}" for h2 in list(header_row2)] #print(new_columns) df.columns = new_columns #print(new_columns) df = df.iloc[2:].reset_index(drop=True) #把前两行数据删除,而不会删除表头 # 添加管理费和托管费的总和列 # 确保列存在且为数值类型,填充NaN为0避免计算错误 df["管+托"] = df["管理费率"].fillna(0) + df["托管费率"].fillna(0) # 处理认or初字段 df["认or初"] = np.where( df["单一or集合"].str.strip().eq("集合"), # 更安全的字符串比较 "认购起点", "初始募集规模" ) # 处理意外值(非单一/集合的情况) unexpected_values = df[~df["单一or集合"].str.strip().isin(["单一", "集合"])] if not unexpected_values.empty: print_debug(f"警告:发现{len(unexpected_values)}条异常值,强制转换为初始募集规模") df.loc[unexpected_values.index, "认or初"] = "初始募集规模" #推质材料输入年月 df = add_material_others_data(df) # excel为空或否,取sql数据 df = merge_sql_data(df) #处理假设场景 df = calculate_loss_scenarios(df) # 处理风险等级映射 risk_mapping = { 'R1(低风险)' :'R1(低风险),但低风险未必带来低收益', 'R2(中低风险)' :'R2(中低风险),但中低风险未必带来中低收益', 'R3(中等风险)' :'R3(中等风险),但中等风险未必带来中等收益', 'R4(中高风险)' :'R4(中高风险),但中高风险未必带来中高收益', 'R5(高风险)' :'R5(高风险),具有高风险的特征,但高风险未必带来高收益' } if '风险等级' in df.columns: df['风险等级(详细)'] = df['风险等级'].str.strip().replace(risk_mapping) else: print_debug("警告:缺少 '风险等级' 列") # 验证必要列 required_
首先,数据处理部分。用户可能需要从Excel中读取数据,可能使用xlwings或者pandas。引用[2]提到xlwings可以自动化Excel,并且支持Windows和macOS,但处理大数据时可能需要优化。所以,我应该建议使用pandas来提高数据处理的效率,尤其是处理大量数据时,pandas的向量化操作比逐行读取更快。另外,数据校验很重要,比如检查必填字段是否存在,或者数据格式是否正确,避免生成PPT时出错。
然后是PPT生成部分。引用[1]和[3]提到使用python-pptx库,但用户可能需要模板应用。所以,建议预先设计好PPT模板,确定占位符的位置,这样在插入数据时可以更准确。比如,标题、内容、图片的位置都预先留好,通过读取模板来替换内容,而不是每次都从头创建,这样可以保持一致的格式,提高效率。
代码结构方面,用户可能需要将功能模块化,比如分成数据加载、模板处理和PPT生成三个部分。这样代码更易维护,也方便后续扩展。另外,异常处理是关键,比如处理文件不存在或数据错误的情况,使用try-except块来捕获异常,并记录日志,方便排查问题。
性能优化方面,如果数据量很大,可以考虑异步生成或者分批次处理,避免内存不足。同时,利用缓存机制,比如预加载模板,避免每次生成都重新读取,减少IO开销。
用户可能还希望有动态内容,比如根据数据生成不同的图表。这时候,可以使用python-pptx的图表功能,或者结合matplotlib生成图表图片,再插入到PPT中。引用[4]提到了一些辅助函数和自动分析,可能用户需要自动生成报告,所以动态图表会很实用。
另外,考虑使用配置文件来管理字段映射和样式设置,这样用户不需要修改代码就能调整PPT的样式,比如字体、颜色等。通过JSON或YAML文件定义这些配置,提高脚本的灵活性。
测试部分,建议用户使用虚拟数据测试脚本的各个部分,确保每个模块正常工作。特别是边界情况,比如空数据、特殊字符等,确保脚本的健壮性。
总结下来,优化点包括:使用pandas高效处理数据、预定义PPT模板、模块化代码结构、异常处理、动态图表生成、配置管理以及性能优化措施。这些步骤应该能帮助用户提升脚本的效率和可维护性。### 分步优化方案
一、数据处理优化
使用Pandas替代逐行读取
将Excel数据一次性读入DataFrame,利用向量化操作提升效率:import pandas as pd import xlwings as xw def load_excel_data(file_path, sheet_name): try: df = pd.read_excel(file_path, sheet_name=sheet_name) # 数据校验(示例) required_columns = ["姓名", "奖项", "日期"] if not set(required_columns).issubset(df.columns): raise ValueError("缺少必填字段") return df except Exception as e: print(f"数据加载失败: {str(e)}") return None
动态字段映射
通过配置文件定义Excel列与PPT占位符的对应关系(如JSON):{ "field_mapping": { "姓名": "{{name}}", "奖项": "{{award}}", "日期": "{{date}}" } }
二、PPT模板应用优化
预定义模板占位符
在PPT模板中使用{{}}
标记占位符,通过遍历形状快速替换(引用[1][3]):from pptx import Presentation def apply_template(template_path, slide_data): prs = Presentation(template_path) slide = prs.slides[0] # 假设使用第一页 for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: for run in paragraph.runs: for key, value in slide_data.items(): run.text = run.text.replace(f"{{{{{key}}}}}", str(value)) return prs
批量生成与样式继承
通过复制母版样式确保格式统一,避免重复设置字体/颜色:def duplicate_slide_with_style(prs, layout_name): slide_layout = prs.slide_layouts.get_by_name(layout_name) new_slide = prs.slides.add_slide(slide_layout) return new_slide
三、性能提升关键点
异步生成与缓存
使用concurrent.futures
实现多线程生成,预加载模板减少IO开销:from concurrent.futures import ThreadPoolExecutor def batch_generate_ppt(data_list, template_path): with ThreadPoolExecutor() as executor: futures = [executor.submit(apply_template, template_path, data) for data in data_list] results = [f.result() for f in futures] return results
内存管理
分块处理大型Excel文件,避免一次性加载全部数据:chunk_size = 100 # 按100行分块读取 for chunk in pd.read_excel("large_file.xlsx", chunksize=chunk_size): process_chunk(chunk)
四、错误处理与日志
- 异常捕获与重试机制
import logging logging.basicConfig(filename="ppt_generator.log", level=logging.ERROR) def safe_generate(data): try: prs = apply_template("template.pptx", data) prs.save(f"output_{data['id']}.pptx") except PermissionError: logging.error("文件被其他进程占用,重试中...") time.sleep(1) safe_generate(data) # 简单重试逻辑
进阶功能扩展
- 自动化图表插入(引用[4])
将Excel数据通过Matplotlib生成图表后插入PPT:import matplotlib.pyplot as plt from pptx.util import Inches def add_chart_to_slide(slide, df, chart_type="bar"): fig = plt.figure() df.plot(kind=chart_type) fig.savefig("temp_chart.png") slide.shapes.add_picture("temp_chart.png", Inches(1), Inches(1), width=Inches(4))
最终脚本架构
├── config.json # 字段映射配置
├── templates/
│ └── certificate.pptx # PPT模板文件
├── main.py # 主逻辑
└── utils/
├── excel_loader.py # 数据加载模块
└── ppt_generator.py # PPT生成模块
相关推荐


















