Python GUI生成Word模板报错TypeError: string indices must be integers求助
问题修复方案
错误原因分析
报错TypeError: string indices must be integers的核心问题:
valuesnew是用户表单字典与df.to_dict()(默认按列生成的字典)合并后的结果,直接遍历它时,迭代的是字典的键(字符串类型),而非数据记录,因此record['Hazard_ID']会报错——字符串无法用字典索引。df.to_dict()默认生成的是整列数据的字典,不符合你按行处理Excel数据的需求。
修复后的完整代码
# Import Packages import datetime from pathlib import Path import PySimpleGUI as sg from docxtpl import DocxTemplate import pandas as pd # Define Paths document_path = Path(__file__).parent / "Template.docx" base_dir = Path(__file__).parent excel_path = base_dir / "excel_data.xlsx" output_dir = base_dir / "OUTPUT" # Create output folder for the word documents output_dir.mkdir(exist_ok=True) # Convert Excel sheet to pandas dataframe, 按行转换为字典列表 df = pd.read_excel(excel_path, sheet_name="Sheet1") records = df.to_dict('records') # 关键修改:将每行转为字典,生成记录列表 # Layout of user form: layout = [ [sg.Text("Project:"), sg.Input(key="Project", do_not_clear=False)], [sg.Text("Part Number:"), sg.Input(key="Part_Number", do_not_clear=False)], [sg.Text("Identity:"), sg.Input(key="Assessment_Form_Number", do_not_clear=False)], [sg.Text("Assessed By:"), sg.Input(key="Assessed_By", do_not_clear=False)], [sg.Text("Assigned Role:"), sg.Input(key="Assigned_Role", do_not_clear=False)], [sg.Text("Date:"), sg.Input(key="Date", do_not_clear=False)], [sg.Button("Create Hazard Assessment Form(s)"), sg.Exit()], ] window = sg.Window("Hazard Assessment Form Generator", layout, element_justification="right") # Conditions: while True: event, values = window.read() if event == sg.WIN_CLOSED or event == "Exit": break if event == "Create Hazard Assessment Form(s)": # 遍历Excel中的每一条记录 for record in records: # 合并用户输入与当前行记录 render_data = {**values, **record} # 每次渲染前重新加载模板,避免重复渲染导致的内容叠加 doc = DocxTemplate(document_path) doc.render(render_data) # 生成输出路径,使用当前记录的Hazard_ID命名 output_path = output_dir / f"Folder-{record['Hazard_ID']}.docx" doc.save(output_path) sg.popup("批量生成完成", f"所有文件已保存至: {output_dir}") window.close()
关键修改点说明
- Excel数据格式转换:
- 替换
df.to_dict()为df.to_dict('records'),将Excel每行数据转为独立字典,形成记录列表,满足按行处理的需求。
- 替换
- 循环逻辑修正:
- 遍历
records(Excel行记录列表)而非valuesnew,确保record是包含Hazard_ID的字典结构。
- 遍历
- 模板重新加载:
- 每次循环重新创建
DocxTemplate实例,避免重复渲染导致旧内容残留叠加。
- 每次循环重新创建
- 数据合并优化:
- 使用
{**values, **record}合并用户表单数据与Excel行记录,若存在重复键,用户输入会优先覆盖。
- 使用
- 输出路径规范:
- 将生成的文档统一存入预先创建的
OUTPUT目录,避免文件混乱。
- 将生成的文档统一存入预先创建的
额外实用建议
- 日期输入可改用日历选择组件,避免手动输入格式错误:
[sg.Text("Date:"), sg.Input(key="Date", do_not_clear=False), sg.CalendarButton("选择日期", target="Date", format="%Y-%m-%d")] - 可添加表单必填项校验,比如检查所有输入框非空后再执行生成操作,提升程序健壮性。
内容的提问来源于stack exchange,提问作者AM96
相关产品推荐
相关产品推荐

