【办公类】202060909托3班的“家园共育主题墙(贴墙三件套——育儿知识、信息窗、周计划)
2026/9/24 17:15:00 网站建设 项目流程

一、背景需求

9月1日,我用Python+微信,每个班主任发送了自己的班级的”国旗下讲话(有文字版)。

【办公类-119-03】20260901三个园区“国旗下讲话” 按班级组合docx模板(AI+excel+python、deepseek和豆包、微信自动私发)https://mp.csdn.net/mp_blog/creation/editor/164123764

过几天在校门口刷卡时,正好遇到托3班的班主任S老师,她热情地表示感谢说:

“阿夏,你太厉害了,把国旗下讲话都做好了!这个太方便了!我和G老师年纪大了,看电脑都看不清(老花眼),你做这个真的帮了大忙了!”

我想到托3班今年的特殊情况:

1.两位班主任都超过50岁了,年长者都会有“老花眼”问题。

(一般班级总是一位年轻教师和一位老教师搭班,因此电子资料由年轻老师写。但是缩班后,实在凑不到年轻老师,而且其中一位老教师正好明年6月退休。)

2.托3班是今年新增的托班,并没有现成的托班资料。

(2024和2025学年都只有2个托班——托1班和托2班,2026学年新增托3班,意味着托3班今年重新做一套新资料,这对两位老教师来说更费劲。)

所以我提出用编程给托3班做“家园共育主题墙(贴墙四件套)”班主任欣然应允。

二、分析托班资料结构和板式

20260909正好去一分园带班,拍摄了托1班和托2班的家园共育主题墙。

托2班:有周计划、育儿知识、信息窗(没有主题知识)

托1班:有周计划、育儿知识、信息窗(没有主题知识)

因为托3班用的就是托1班的资料,所以我没份都特写拍摄,

然后我又问二分园托3班要了他们的家园共育主题墙版面,

和托1班的样式一模一样(用了白纸)也是只有周计划、育儿知识、信息窗(没有主题知识)

把下载的资料分类

二、制作“育儿知识”

(一)制作Word模版

1.复制并制作word模版

2.更换背景图

还需要更换内容和教师名字。

3.豆包制作背景图

我选了第一个

用PPT修图

不好修图,

很好,统一白色255、255、255后,冲蚀效果很干净(透明色)

4.添加占位符字母

(二)制作excle标题

把“四大教育”代码复制一下

''' 育儿知识(托3班) excle的列标题制作(占位符字母) 豆包、Deepseek、阿夏 2026096 ''' import pandas as pd import os # ========== 路径配置 ========== BASE_PATH = r'D:\Python最终内容\20260909托3班资料制作\00育儿知识' CLASS_NAME = "托3班" EDU_THEME = "全部主题" date = '20260910' EXCEL_PATH = os.path.join(BASE_PATH, f"{date}{CLASS_NAME}育儿知识({EDU_THEME}).xlsx") # 表头字段【已改成docx模板里面{{}}内的标识符】 columns = [ 'title', 'content', 'T1','T2','classroom','yearmonth' ] def create_empty_excel_header_only(): """只生成仅有表头的Excel,没有数据行""" os.makedirs(BASE_PATH, exist_ok=True) df = pd.DataFrame(columns=columns) df.to_excel(EXCEL_PATH, index=False) print(f"✅ 已生成仅带表头的Excel") print(f"📂 文件路径:{EXCEL_PATH}") print(f"📋 表头:{columns}") if __name__ == "__main__": create_empty_excel_header_only()

(三)豆包制作文字

我希望根据附件 9-1 月的育儿知识内容,重新生成相似的内容(标题 title 和内容 content 都不能一模一样)、content 大约 450-480 字,要制作 3-6 段文字,每段用 aaa 分隔,T1 = 赵:T2 = 钱。制作成表格样式。

把Word模版重新制作

生成标题

把AI文字复制到EXCEL内

(四)excle批量生成Word、合并PDF打印

''' 托3班育儿知识5个月主题, 完整工作流 1. 生成占位符Excel 2. 根据Excel生成Word文档 3. 处理Word文档(aaa转手动换行符、空格缩进) 4. 打包成RAR 豆包、Deepseek、阿夏 20260910 ''' import pandas as pd from docxtpl import DocxTemplate from docx import Document from docx.enum.text import WD_BREAK import os import sys import subprocess import zipfile # ========== 全局路径配置(只需修改这里) ========== BASE_PATH = r'D:\Python最终内容\20260909托3班资料制作\00育儿知识' CLASS_NAME = "托3班" EDU_THEME = "全部主题" # ============================================== EXCEL_PATH = os.path.join(BASE_PATH, f"20260910{CLASS_NAME}育儿知识({EDU_THEME}).xlsx") TEMPLATE_PATH = os.path.join(BASE_PATH, "育儿知识模版.docx") OUTPUT_FOLDER = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})育儿知识_{EDU_THEME}") PROCESSED_FOLDER = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})育儿知识_{EDU_THEME}最终") RAR_PATH = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})育儿知识_{EDU_THEME}最终.rar") ZIP_PATH = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})育儿知识_{EDU_THEME}最终.zip") # windows控制台编码 if sys.platform == 'win32': import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') # def step1_generate_excel(): # """第一步:生成占位符Excel文件【育儿知识字段】""" # print("\n" + "="*60) # print("第一步:生成占位符Excel文件") # print("="*60) # os.makedirs(BASE_PATH, exist_ok=True) # # 和docx模板占位符完全对应 # df = pd.DataFrame(columns=[ # 'title', 'content', 'classroom', 'T1', 'T2', 'year', 'month' # ]) # df.to_excel(EXCEL_PATH, index=False) # print(f"✅ Excel文件已生成:{EXCEL_PATH}") # input('\n请先在Excel中填入AI生成的内容,然后按回车键继续...') # return True def step2_generate_word_from_excel(): """第二步:根据Excel生成Word文档""" print("\n" + "="*60) print("第二步:根据Excel生成Word文档") print("="*60) os.makedirs(OUTPUT_FOLDER, exist_ok=True) generated_files = [] if not os.path.exists(EXCEL_PATH): print(f"❌ 错误:Excel不存在 - {EXCEL_PATH}") return False if not os.path.exists(TEMPLATE_PATH): print(f"❌ 错误:模板文件不存在 - {TEMPLATE_PATH}") return False schedule = pd.read_excel(EXCEL_PATH) # 全部字段转字符串,nan替换为空 col_list = ['title','content','classroom','T1','T2','year','month'] for col in col_list: if col in schedule.columns: schedule[col] = schedule[col].astype(str).replace('nan', '') # 设置默认值 if 'classroom' not in schedule.columns: schedule['classroom'] = CLASS_NAME if 'T1' not in schedule.columns: schedule['T1'] = '' if 'T2' not in schedule.columns: schedule['T2'] = '' if 'year' not in schedule.columns: schedule['year'] = '2026' if 'month' not in schedule.columns: schedule['month'] = '9' schedule.to_excel(EXCEL_PATH, index=False) print(f"✅ 已保存安排表") print(f"📊 安排表共有 {len(schedule)} 行数据") # 校验模板 try: Document(TEMPLATE_PATH) print("✅ 模板文件验证通过,开始生成文档...") except Exception as e: print(f"❌ 模板文件无效: {e}") return False # 循环逐行渲染模板 for index, row in schedule.iterrows(): try: tpl = DocxTemplate(TEMPLATE_PATH) classroom = str(row['classroom']).strip() if pd.notna(row['classroom']) else CLASS_NAME # 模板上下文 和 {{占位符}}一一对应 context = { "title": str(row['title']) if pd.notna(row['title']) else "", "content": str(row['content']) if pd.notna(row['content']) else "", "classroom": classroom, "T1": str(row['T1']) if pd.notna(row['T1']) else "", "T2": str(row['T2']) if pd.notna(row['T2']) else "", "year": str(row['year']) if pd.notna(row['year']) else "2026", "month": str(row['month']) if pd.notna(row['month']) else "9", } tpl.render(context) temp_path = os.path.join(OUTPUT_FOLDER, f"temp_{index}.docx") tpl.save(temp_path) doc = Document(temp_path) # 文件名 month_str = str(row['month']) if pd.notna(row['month']) else str(index+1) title_short = str(row['title'])[:15] if pd.notna(row['title']) else "育儿知识" filename = f"{title_short}({month_str}月).docx" file_full_path = os.path.join(OUTPUT_FOLDER, filename) doc.save(file_full_path) if os.path.exists(temp_path): os.remove(temp_path) generated_files.append(file_full_path) print(f"✅ 生成文档: {filename}") except Exception as e: print(f"❌ 生成第{index+1}行文档失败: {str(e)}") import traceback traceback.print_exc() continue print(f"\n📊 文档生成完成!共生成 {len(generated_files)} 个文档") print(f"📂 文档保存在: {OUTPUT_FOLDER}") return True def process_word_document(input_path, output_path): """处理单个Word文档:aaa替换为手动换行符""" try: doc = Document(input_path) modified = False # 遍历所有段落,处理aaa分隔符 for para in doc.paragraphs: if 'aaa' in para.text: runs_info = [] for run in para.runs: runs_info.append({ 'text': run.text, 'bold': run.bold, 'italic': run.italic, 'underline': run.underline, 'font_name': run.font.name, 'font_size': run.font.size, }) full_text = para.text parts = full_text.split('aaa') para.clear() for i, part in enumerate(parts): if part.strip(): run = para.add_run(part) if runs_info: run.bold = runs_info[0]['bold'] run.italic = runs_info[0]['italic'] run.underline = runs_info[0]['underline'] run.font.name = runs_info[0]['font_name'] run.font.size = runs_info[0]['font_size'] if i < len(parts) - 1: para.add_run().add_break(WD_BREAK.LINE) modified = True doc.save(output_path) return os.path.exists(output_path), modified except Exception as e: print(f" 错误: {str(e)}") import traceback traceback.print_exc() return False, False def step3_process_documents(): """第三步:处理word文档 aaa转手动换行""" print("\n" + "="*60) print("第三步:处理Word文档(aaa转手动换行符)") print("="*60) os.makedirs(PROCESSED_FOLDER, exist_ok=True) print(f"输入文件夹: {OUTPUT_FOLDER}") print(f"输出文件夹: {PROCESSED_FOLDER}") if not os.path.exists(OUTPUT_FOLDER): print(f"❌ 错误: 输入文件夹不存在!") return False docx_files = [f for f in os.listdir(OUTPUT_FOLDER) if f.lower().endswith('.docx')] if not docx_files: print(f"⚠️ 没有找到docx文件!") return False print(f"\n✅ 找到 {len(docx_files)} 个docx文件") success = 0 for i, filename in enumerate(docx_files, 1): print(f"[{i}/{len(docx_files)}] {filename}") input_path = os.path.join(OUTPUT_FOLDER, filename) output_filename = filename.replace('.docx', '.doc') output_path = os.path.join(PROCESSED_FOLDER, output_filename) result, modified = process_word_document(input_path, output_path) if result: print(f" ✅ 已处理保存") success +=1 else: print(f" ❌ 处理失败") print() print(f"\n✅ 处理完成!成功处理 {success}/{len(docx_files)} 个文件") print(f"📂 处理后文档保存在: {PROCESSED_FOLDER}") return True def check_winrar_installed(): """检查WinRAR""" possible_paths = [ r"C:\Program Files\WinRAR\WinRAR.exe", r"C:\Program Files (x86)\WinRAR\WinRAR.exe" ] for path in possible_paths: if os.path.exists(path): return path return None def create_zip_backup(): """无WinRAR时生成zip""" try: print("🔄 正在创建ZIP压缩文件...") with zipfile.ZipFile(ZIP_PATH, 'w', zipfile.ZIP_DEFLATED) as zipf: for root, _, files in os.walk(PROCESSED_FOLDER): for file in files: fp = os.path.join(root, file) arc = os.path.relpath(fp, PROCESSED_FOLDER) zipf.write(fp, arc) if os.path.exists(ZIP_PATH): size_kb = os.path.getsize(ZIP_PATH)/1024 print(f"✅ ZIP打包成功!size:{size_kb:.2f}KB") print("注意:没有WinRAR,输出为zip,需要rar请手动安装WinRAR") return True return False except Exception as e: print(f"❌ ZIP打包出错:{e}") return False def step4_pack_to_rar(): """第四步:打包RAR/ZIP""" print("\n" + "="*60) print("第四步:打包成RAR文件") print("="*60) if not os.path.exists(PROCESSED_FOLDER): print(f"❌ 错误:最终文件夹不存在 {PROCESSED_FOLDER}") return False file_list = os.listdir(PROCESSED_FOLDER) if len(file_list) == 0: print(f"⚠️ 文件夹为空,跳过打包") return False winrar_exe = check_winrar_installed() if winrar_exe: try: cmd = [winrar_exe, 'a','-ep1','-r',RAR_PATH,f'{PROCESSED_FOLDER}\\*.*'] subprocess.run(cmd, capture_output=True, text=True) if os.path.exists(RAR_PATH): kb = os.path.getsize(RAR_PATH)/1024 print(f"✅ RAR打包成功 {RAR_PATH} 大小{kb:.2f}KB") return True except Exception as e: print(f"WinRAR异常 {e},回退zip") print("未检测WinRAR,执行zip打包") return create_zip_backup() def main(): print("\n" + "="*60) print("托3班育儿知识完整工作流") print("="*60) print(f"基础路径:{BASE_PATH} 班级:{CLASS_NAME} 主题:{EDU_THEME}") print("="*60) # 步骤1:生成Excel占位表(需要手动填数据后回车继续) # if not step1_generate_excel(): # print("❌第一步失败退出") # return # 步骤2:excel批量生成word if not step2_generate_word_from_excel(): print("❌第二步失败退出") return # 步骤3:处理aaa换行 if not step3_process_documents(): print("❌第三步失败退出") return # 步骤4:压缩包 step4_pack_to_rar() print("\n" + "="*60) print("🎉全部流程完成") print(f"1.Excel:{EXCEL_PATH}") print(f"2.原始word:{OUTPUT_FOLDER}") print(f"3.处理后word:{PROCESSED_FOLDER}") if os.path.exists(RAR_PATH): print(f"4.RAR包:{RAR_PATH}") elif os.path.exists(ZIP_PATH): print(f"4.ZIP包:{ZIP_PATH}") print("="*60) if __name__ == "__main__": main()

未完待续

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询