一、背景需求
2026年8月27日,语言文字组长就发过国旗下讲话模版了
我问三个园区三位老师收集了相关安排表和模版



分别下载到制作的文件夹里




因为老电脑坏了,所有的模版都没有导出来,因此只智能重做word和Excel模版。
幸好做过一套csdn的备份,有word和Excel模版的样式和py代码
二、word模版
(一)分园模版
托小班的模版(一分园、二分园),两个园区的模版一模一样(副标题的园区不同),本次我只做一个通用模版

转为docx


根据图片演示,修改内部占位符






(二)总部模版





三、Excel模版制作
(一)Python提取安排表内容到Excel内
过去式从word里面复制信息,现在我想做一个Python程序,提取word里面的信息。
把学校、教师姓名隐藏或改名








括号不一样,换一种括号


一样了






更改周次



更改日期



AI改起来太快了
python
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
# 原始数据
data = [
["第一周", "9月1日", "交通安全一盔一带", "张三+小5班"],
["第二周", "9月7日", "老师节日快乐", "李四+小4班"],
["第三周", "9月14日", "普通话推广周", "王五+托2班"],
["第四周", "9/20---9/24", "爱眼护眼", "张三+托1班"],
["第五周", "9/28---9/30", "喜迎国庆节", "李四+小5班"],
["第六周", "10/8---10/10", "谨防电信诈骗", "王五+小4班"],
["第七周", "10月12日", "保护地球", "张三+托2班"],
["第八周", "10月19日", "我爱运动", "李四+托1班"],
["第九周", "10月26日", "珍惜粮食不浪费", "王五+小5班"],
["第十周", "11月2日", "消防安全月", "张三+小4班"],
["第十一周", "11月9日", "预防传染病", "李四+托2班"],
["第十二周", "11月16日", "劳动最光荣", "王五+托1班"],
["第十三周", "11月23日", "爱护小动物", "张三+小5班"],
["第十四周", "11月30日", "我会刷牙和漱口", "李四+小4班"],
["第十五周", "12月7日", "交通安全", "王五+托2班"],
["第十六周", "12月14日", "我爱老师和同伴", "张三+托1班"],
["第十七周", "12月21日", "食品安全", "张三+小5班"],
["第十八周", "12月28日", "迎接2027年", "李四+小4班"],
["第十九周", "1月4日", "防拐防骗", "王五+托2班"]
]
df = pd.DataFrame(data, columns=["周次", "时间", "主题", "行政+班级"])
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
"""
格式转换:
9月1日 → 2026.9.1
9/20---9/24 → 2026.9.20‑2026.9.24
1月4日 → 2027.1.4
"""
txt = txt.strip()
# 区间格式 9/20---9/24 、10/8---10/10
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
# 如果第二个月是1月,则第二年
if int(m2) == 1:
y2 = 2027
else:
y2 = 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
# 单日期:9月1日 / 1月4日
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 1.拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
# 2.班级格式转换:小5班 → 小(5)班;托2班 → 托(2)班
def format_class_name(s):
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 创建输出文件夹
out_dir = r"D:\Python最终内容\20260906国旗下讲话\01一分园"
os.makedirs(out_dir, exist_ok=True)
excel_path = os.path.join(out_dir, "XXXX一分园2026.9‑2027.1升旗仪式讲话安排.xlsx")
# 写出Excel
df.to_excel(excel_path, index=False, engine="openpyxl")
# ========== 手动指定列宽 ==========
# 5列顺序:周次、时间、主题、行政老师、班级
col_widths = [10, 25, 25, 20, 10]
wb = load_workbook(excel_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx + 1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_path)
wb.close()
print(f"✅已生成:{excel_path}")
print(df.to_string())






结果不能运行


需要把幼儿信息五人一组导入。












python
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
# ---------------------- 国旗下讲话原始数据 ----------------------
data = [
["第一周", "9月1日", "交通安全一盔一带", "张三+小5班"],
["第二周", "9月7日", "老师节日快乐", "李四+小4班"],
["第三周", "9月14日", "普通话推广周", "王五+托2班"],
["第四周", "9/20---9/24", "爱眼护眼", "张三+托1班"],
["第五周", "9/28---9/30", "喜迎国庆节", "李四+小5班"],
["第六周", "10/8---10/10", "谨防电信诈骗", "王五+小4班"],
["第七周", "10月12日", "保护地球", "张三+托2班"],
["第八周", "10月19日", "我爱运动", "李四+托1班"],
["第九周", "10月26日", "珍惜粮食不浪费", "王五+小5班"],
["第十周", "11月2日", "消防安全月", "张三+小4班"],
["第十周", "11月9日", "预防传染病", "李四+托2班"],
["第十二周", "11月16日", "劳动最光荣", "王五+托1班"],
["第十三周", "11月23日", "爱护小动物", "张三+小5班"],
["第十四周", "11月30日", "我会刷牙和漱口", "李四+小4班"],
["第十五周", "12月7日", "交通安全", "王五+托2班"],
["第十六周", "12月14日", "我爱老师和同伴", "张三+托1班"],
["第十七周", "12月21日", "食品安全", "张三+小5班"],
["第十八周", "12月28日", "迎接2027年", "李四+小4班"],
["第十九周", "1月4日", "防拐防骗", "王五+托2班"]
]
df = pd.DataFrame(data, columns=["周次", "时间", "主题", "行政+班级"])
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
txt = txt.strip()
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
y2 = 2027 if int(m2) == 1 else 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
def format_class_name(s):
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 修改原有5列英文表头
df.columns = ["week", "date", "topic", "leader", "classroom"]
# 新增全部空白列
add_cols = ["teacher1","teacher2","s1","s2","s3","s4","s5","sw1","sw2","sw3","sw4","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========【重点】读取多sheet的学生Excel ==========
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01虚拟20260805班级信息表.xlsx"
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
# sheet名称就是班级名,例如"托1班"
cls_key = sheet_name.strip()
name_list = []
# 取姓名列,过滤空值
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 构建模糊匹配映射:从班级字符串提取(类型,数字)
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
# 每个班级独立游标
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5"]
def get_next_five_by_display_name(display_name:str):
"""传入主表显示班级如'小(5)班',模糊匹配取5个学生,自动移动游标,循环"""
m = re.search(r"(托|小)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*5
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*5
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*5
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
while len(out) <5:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充s1‑s5
for idx, row in df.iterrows():
disp_cls = row["classroom"]
five_names = get_next_five_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = five_names[i]
# ----------------------输出Excel----------------------
out_dir = r"D:\Python最终内容\20260906国旗下讲话\01一分园"
os.makedirs(out_dir, exist_ok=True)
excel_path = os.path.join(out_dir, "XXXX一分园2026.9‑2027.1升旗仪式讲话安排.xlsx")
df.to_excel(excel_path, index=False, engine="openpyxl")
col_widths = [10, 25, 25, 15, 15,
10, 10, 10, 10, 10,
10, 10, 10, 10, 10,
10, 10]
wb = load_workbook(excel_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_path)
wb.close()
print(f"\n✅已生成:{excel_path}")
print(df[["week","classroom","s1","s2","s3","s4","s5"]].to_string())

我读取真数据,看看有没有重名。

检查一下名单
托班

小班

需要匹配教师姓名,虚假名单,导入T1、T2



导入了老师,

python
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
# ---------------------- 国旗下讲话原始数据 ----------------------
data = [
["第一周", "9月1日", "交通安全一盔一带", "张三+小5班"],
["第二周", "9月7日", "老师节日快乐", "李四+小4班"],
["第三周", "9月14日", "普通话推广周", "王五+托2班"],
["第四周", "9/20---9/24", "爱眼护眼", "张三+托1班"],
["第五周", "9/28---9/30", "喜迎国庆节", "李四+小5班"],
["第六周", "10/8---10/10", "谨防电信诈骗", "王五+小4班"],
["第七周", "10月12日", "保护地球", "张三+托2班"],
["第八周", "10月19日", "我爱运动", "李四+托1班"],
["第九周", "10月26日", "珍惜粮食不浪费", "王五+小5班"],
["第十周", "11月2日", "消防安全月", "张三+小4班"],
["第十周", "11月9日", "预防传染病", "李四+托2班"],
["第十二周", "11月16日", "劳动最光荣", "王五+托1班"],
["第十三周", "11月23日", "爱护小动物", "张三+小5班"],
["第十四周", "11月30日", "我会刷牙和漱口", "李四+小4班"],
["第十五周", "12月7日", "交通安全", "王五+托2班"],
["第十六周", "12月14日", "我爱老师和同伴", "张三+托1班"],
["第十七周", "12月21日", "食品安全", "张三+小5班"],
["第十八周", "12月28日", "迎接2027年", "李四+小4班"],
["第十九周", "1月4日", "防拐防骗", "王五+托2班"]
]
df = pd.DataFrame(data, columns=["周次", "时间", "主题", "行政+班级"])
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
txt = txt.strip()
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
y2 = 2027 if int(m2) == 1 else 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
def format_class_name(s):
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 修改原有5列英文表头
df.columns = ["week", "date", "topic", "leader", "classroom"]
# 新增全部空白列
add_cols = ["teacher1","teacher2","s1","s2","s3","s4","s5","sw1","sw2","sw3","sw4","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========读取老师名单:03虚假微信发送名单.xlsx==========
# teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 虚假微信发送名单.xlsx"
teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 微信发送名单.xlsx"
df_teacher = pd.read_excel(teacher_file)
teacher_dict = {}
for cls, group in df_teacher.groupby("班级"):
names = []
for _,r in group.iterrows():
nm = str(r["姓名"]).strip()
if pd.notna(nm) and nm!="":
names.append(nm)
t1 = names[0] if len(names)>=1 else ""
t2 = names[1] if len(names)>=2 else ""
teacher_dict[str(cls).strip()] = (t1, t2)
print("老师字典",teacher_dict)
# ==========读取多sheet学生名单==========
# stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 虚拟20260805班级信息表.xlsx"
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 20260805班级信息表.xlsx"
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
cls_key = sheet_name.strip()
name_list = []
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 模糊匹配映射 学生
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5"]
def get_next_five_by_display_name(display_name:str):
m = re.search(r"(托|小)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*5
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*5
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*5
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
while len(out) <5:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充 teacher1 teacher2 + s1‑s5
for idx, row in df.iterrows():
disp_cls = row["classroom"]
#解析班级标识:小(5)班 → 小5
m_cls = re.search(r"(托|小)[^\d]*(\d+)", disp_cls)
if m_cls:
pre, num = m_cls.groups()
cls_short = f"{pre}{num}"
t1,t2 = teacher_dict.get(cls_short, ("",""))
df.at[idx,"teacher1"] = t1
df.at[idx,"teacher2"] = t2
#填充学生
five_names = get_next_five_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = five_names[i]
# ----------------------输出Excel----------------------
out_dir = r"D:\Python最终内容\20260906国旗下讲话\01一分园"
os.makedirs(out_dir, exist_ok=True)
excel_path = os.path.join(out_dir, "XXXX一分园2026.9‑2027.1升旗仪式讲话安排.xlsx")
df.to_excel(excel_path, index=False, engine="openpyxl")
col_widths = [10, 25, 25, 15, 15,
12, 12, 10, 10, 10,
10, 10, 10, 10, 10,
10, 10]
wb = load_workbook(excel_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_path)
wb.close()
print(f"\n✅已生成:{excel_path}")
print(df[["week","classroom","teacher1","teacher2","s1","s2","s3","s4","s5"]].to_string())
教师名字都对了
(一)一分园










python
'''
一分园基础数据提取
豆包,阿夏
202060827
'''
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from docx import Document
def read_speech_table(docx_path):
"""读取docx文档第一个表格,按列序号提取,解决表头异常KeyError"""
doc = Document(docx_path)
table = doc.tables[0]
rows_data = []
for r in table.rows:
cells = [c.text.strip() for c in r.cells]
rows_data.append(cells)
# 跳过表头第一行,直接按索引取0,1,2,3四列
out_rows = []
for row in rows_data[1:]:
if len(row)>=4:
out_rows.append({
"周次": row[0],
"时间": row[1],
"主题": row[2],
"行政+班级": row[3]
})
raw_df = pd.DataFrame(out_rows)
raw_df = raw_df.dropna(how="all")
raw_df = raw_df[raw_df["周次"] != ""]
return raw_df
# =========配置文件路径=========
docx_speech_file = r"D:\Python最终内容\20260906国旗下讲话\01一分园\国旗下的讲话总安排(一分部) 2026.9(1).docx"
teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 微信发送名单.xlsx"
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 20260805班级信息表.xlsx"
out_dir = r"D:\Python最终内容\20260906国旗下讲话\01一分园"
excel_out_path = os.path.join(out_dir, "一分园.xlsx")
# 读取word里面的讲话安排
df = read_speech_table(docx_speech_file)
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
txt = txt.strip()
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
y2 = 2027 if int(m2) == 1 else 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
def format_class_name(s):
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 修改原有5列为英文
df.columns = ["week", "date", "topic", "leader", "classroom"]
# 【新增garden列,全部填充一分园,放在第一列】
df.insert(0, "garden", "一分园")
# 新增其余空白列
add_cols = ["teacher1","teacher2","s1","s2","s3","s4","s5","sw1","sw2","sw3","sw4","sw5","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========读取老师名单==========
df_teacher = pd.read_excel(teacher_file)
teacher_dict = {}
for cls, group in df_teacher.groupby("班级"):
names = []
for _,r in group.iterrows():
nm = str(r["姓名"]).strip()
if pd.notna(nm) and nm!="":
names.append(nm)
t1 = names[0] if len(names)>=1 else ""
t2 = names[1] if len(names)>=2 else ""
teacher_dict[str(cls).strip()] = (t1, t2)
print("老师字典",teacher_dict)
# ==========读取多sheet学生名单==========
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
cls_key = sheet_name.strip()
name_list = []
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 模糊匹配映射 学生
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5"]
def get_next_five_by_display_name(display_name:str):
m = re.search(r"(托|小)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*5
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*5
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*5
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
# =========全部班级统一取5人,人数不够自动循环从头取=========
while len(out) < 5:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充 teacher1 teacher2 + s1‑s5
for idx, row in df.iterrows():
disp_cls = row["classroom"]
m_cls = re.search(r"(托|小)[^\d]*(\d+)", disp_cls)
if m_cls:
pre, num = m_cls.groups()
cls_short = f"{pre}{num}"
t1,t2 = teacher_dict.get(cls_short, ("",""))
df.at[idx,"teacher1"] = t1
df.at[idx,"teacher2"] = t2
five_names = get_next_five_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = five_names[i]
# ----------------------输出Excel----------------------
os.makedirs(out_dir, exist_ok=True)
df.to_excel(excel_out_path, index=False, engine="openpyxl")
# 总列:garden week date topic leader classroom teacher1 teacher2 s1‑s5 sw1‑sw4 tw 一共18列
col_widths = [12,
10, 25, 25, 15, 15,
12, 12, 10, 10, 10,
10, 10, 10, 10, 10,10,
10, 10]
wb = load_workbook(excel_out_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_out_path)
wb.close()
print(f"\n✅已生成:{excel_out_path}")
print(df[["garden","week","classroom","teacher1","teacher2","s1","s2","s3","s4","s5"]].to_string())


(二)二分园



python
'''
二分园基础数据提取
豆包,阿夏
202060827
'''
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from docx import Document
def read_speech_table(docx_path):
"""读取docx文档第一个表格,按列序号提取"""
doc = Document(docx_path)
table = doc.tables[0]
rows_data = []
for r in table.rows:
cells = [c.text.strip() for c in r.cells]
rows_data.append(cells)
# 跳过表头第一行,直接按索引取0,1,2,3四列
out_rows = []
for row in rows_data[1:]:
if len(row)>=4:
out_rows.append({
"周次": row[0],
"时间": row[1],
"主题": row[2],
"行政+班级": row[3]
})
raw_df = pd.DataFrame(out_rows)
raw_df = raw_df.dropna(how="all")
raw_df = raw_df[raw_df["周次"] != ""]
return raw_df
# =========配置文件路径=========
docx_speech_file = r"D:\Python最终内容\20260906国旗下讲话\02二分园\国旗下的讲话总安排(二分部)2026.9.docx"
teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 微信发送名单.xlsx"
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 20260805班级信息表.xlsx"
out_dir = r"D:\Python最终内容\20260906国旗下讲话\02二分园"
excel_out_path = os.path.join(out_dir, "二分园.xlsx")
# 读取word里面的讲话安排
df = read_speech_table(docx_speech_file)
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
txt = txt.strip()
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
y2 = 2027 if int(m2) == 1 else 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
# =====【修复】兼容两种输入:小2 / 小2班,统一输出小(2)班 =====
def format_class_name(s):
s = str(s).strip()
# 如果结尾没有班,补上"班"
if not s.endswith("班"):
s = s + "班"
# 小2班 → 小(2)班
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 修改原有5列为英文
df.columns = ["week", "date", "topic", "leader", "classroom"]
# 【新增garden列,全部填充二分园,放在第一列】
df.insert(0, "garden", "二分园")
# 新增其余空白列
add_cols = ["teacher1","teacher2","s1","s2","s3","s4","s5","sw1","sw2","sw3","sw4","sw5","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========读取老师名单==========
df_teacher = pd.read_excel(teacher_file)
teacher_dict = {}
for cls, group in df_teacher.groupby("班级"):
names = []
for _,r in group.iterrows():
nm = str(r["姓名"]).strip()
if pd.notna(nm) and nm!="":
names.append(nm)
t1 = names[0] if len(names)>=1 else ""
t2 = names[1] if len(names)>=2 else ""
teacher_dict[str(cls).strip()] = (t1, t2)
print("老师字典",teacher_dict)
# ==========读取多sheet学生名单==========
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
cls_key = sheet_name.strip()
name_list = []
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 模糊匹配映射 学生
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5"]
def get_next_five_by_display_name(display_name:str):
m = re.search(r"(托|小)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*5
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*5
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*5
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
while len(out) <5:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充 teacher1 teacher2 + s1‑s5
for idx, row in df.iterrows():
disp_cls = row["classroom"]
m_cls = re.search(r"(托|小)[^\d]*(\d+)", disp_cls)
if m_cls:
pre, num = m_cls.groups()
cls_short = f"{pre}{num}"
t1,t2 = teacher_dict.get(cls_short, ("",""))
df.at[idx,"teacher1"] = t1
df.at[idx,"teacher2"] = t2
five_names = get_next_five_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = five_names[i]
# ----------------------输出Excel----------------------
os.makedirs(out_dir, exist_ok=True)
df.to_excel(excel_out_path, index=False, engine="openpyxl")
# 总列:garden week date topic leader classroom teacher1 teacher2 s1‑s5 sw1‑sw4 tw 一共18列
col_widths = [12,
10, 25, 25, 15, 15,
12, 12, 10, 10, 10,
10, 10, 10, 10, 10,10,
10, 10]
wb = load_workbook(excel_out_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_out_path)
wb.close()
print(f"\n✅已生成:{excel_out_path}")
print(df[["garden","week","classroom","teacher1","teacher2","s1","s2","s3","s4","s5"]].to_string())



python
'''
二分园基础数据提取
豆包,阿夏
202060827
'''
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from docx import Document
def read_speech_table(docx_path):
"""读取docx文档第一个表格,按列序号提取"""
doc = Document(docx_path)
table = doc.tables[0]
rows_data = []
for r in table.rows:
cells = [c.text.strip() for c in r.cells]
rows_data.append(cells)
# 跳过表头第一行,直接按索引取0,1,2,3四列
out_rows = []
for row in rows_data[1:]:
if len(row)>=4:
out_rows.append({
"周次": row[0],
"时间": row[1],
"主题": row[2],
"行政+班级": row[3]
})
raw_df = pd.DataFrame(out_rows)
raw_df = raw_df.dropna(how="all")
raw_df = raw_df[raw_df["周次"] != ""]
return raw_df
# =========配置文件路径=========
docx_speech_file = r"D:\Python最终内容\20260906国旗下讲话\02二分园\国旗下的讲话总安排(二分部)2026.9.docx"
teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 微信发送名单.xlsx"
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 20260805班级信息表.xlsx"
out_dir = r"D:\Python最终内容\20260906国旗下讲话\02二分园"
excel_out_path = os.path.join(out_dir, "二分园.xlsx")
# 读取word里面的讲话安排
df = read_speech_table(docx_speech_file)
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
def convert_date_text(txt):
txt = txt.strip()
m_range = re.match(r"(\d+)/(\d+)---(\d+)/(\d+)", txt)
if m_range:
m1, d1, m2, d2 = m_range.groups()
y1 = 2026
y2 = 2027 if int(m2) == 1 else 2026
return f"{y1}.{m1}.{d1}-{y2}.{m2}.{d2}"
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
return f"{year}.{mon}.{day}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 拆分行政、班级
df[["行政老师", "班级"]] = df["行政+班级"].str.split("+", expand=True)
df.drop(columns=["行政+班级"], inplace=True)
# =====【修复】兼容两种输入:小2 / 小2班,统一输出小(2)班 =====
def format_class_name(s):
s = str(s).strip()
# 如果结尾没有班,补上"班"
if not s.endswith("班"):
s = s + "班"
# 小2班 → 小(2)班
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 修改原有5列为英文
df.columns = ["week", "date", "topic", "leader", "classroom"]
# 【新增garden列,全部填充二分园,放在第一列】
df.insert(0, "garden", "二分园")
# 新增其余空白列
add_cols = ["teacher1","teacher2","s1","s2","s3","s4","s5","sw1","sw2","sw3","sw4","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========读取老师名单==========
df_teacher = pd.read_excel(teacher_file)
teacher_dict = {}
for cls, group in df_teacher.groupby("班级"):
names = []
for _,r in group.iterrows():
nm = str(r["姓名"]).strip()
if pd.notna(nm) and nm!="":
names.append(nm)
t1 = names[0] if len(names)>=1 else ""
t2 = names[1] if len(names)>=2 else ""
teacher_dict[str(cls).strip()] = (t1, t2)
print("老师字典",teacher_dict)
# ==========读取多sheet学生名单==========
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
cls_key = sheet_name.strip()
name_list = []
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 模糊匹配映射 学生
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5"]
def get_next_five_by_display_name(display_name:str):
m = re.search(r"(托|小)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*5
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*5
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*5
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
while len(out) <5:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充 teacher1 teacher2 + s1‑s5
for idx, row in df.iterrows():
disp_cls = row["classroom"]
m_cls = re.search(r"(托|小)[^\d]*(\d+)", disp_cls)
if m_cls:
pre, num = m_cls.groups()
cls_short = f"{pre}{num}"
t1,t2 = teacher_dict.get(cls_short, ("",""))
df.at[idx,"teacher1"] = t1
df.at[idx,"teacher2"] = t2
five_names = get_next_five_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = five_names[i]
# ----------------------输出Excel----------------------
os.makedirs(out_dir, exist_ok=True)
df.to_excel(excel_out_path, index=False, engine="openpyxl")
# 总列:garden week date topic leader classroom teacher1 teacher2 s1‑s5 sw1‑sw4 tw 一共18列
col_widths = [12,
10, 25, 25, 15, 15,
12, 12, 10, 10, 10,
10, 10, 10, 10, 10,
10, 10]
wb = load_workbook(excel_out_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_out_path)
wb.close()
print(f"\n✅已生成:{excel_out_path}")
print(df[["garden","week","classroom","teacher1","teacher2","s1","s2","s3","s4","s5"]].to_string())

(三)总园







套用后发现总园的国旗安排表与分园不一样。



两个表格差异过大,还是要AI来提取












python
'''
总园基础数据提取
豆包,阿夏
202060827
'''
import os
import re
import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from docx import Document
from datetime import datetime, timedelta
def read_speech_table_zongyuan(docx_path):
"""适配总园word表格:列0周次,列1时间,列2行政老师,列4班级,列5主题"""
doc = Document(docx_path)
table = doc.tables[0]
rows_data = []
for r in table.rows:
cells = [c.text.strip() for c in r.cells]
rows_data.append(cells)
out_rows = []
for row in rows_data[1:]:
if len(row)>=6:
out_rows.append({
"周次": row[0],
"时间": row[1],
"行政老师": row[2],
"班级": row[4],
"主题": row[5]
})
raw_df = pd.DataFrame(out_rows)
raw_df = raw_df.dropna(how="all")
raw_df = raw_df[raw_df["周次"] != ""]
return raw_df
# =========配置文件路径=========
docx_speech_file = r"D:\Python最终内容\20260906国旗下讲话\03总园\国旗下的讲话总安排(总园)2026.9(1).docx"
teacher_file = r"D:\Python最终内容\20260906国旗下讲话\03 微信发送名单.xlsx"
stu_file = r"D:\Python最终内容\20260906国旗下讲话\01 20260805班级信息表.xlsx"
out_dir = r"D:\Python最终内容\20260906国旗下讲话\03总园"
excel_out_path = os.path.join(out_dir, "总园.xlsx")
# 读取总园word讲话表
df = read_speech_table_zongyuan(docx_speech_file)
# 汉字数字转阿拉伯数字:第一周 → 第1周
chinese_num = {"一":1,"二":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9,"十":10,"十一":11,"十二":12,"十三":13,"十四":14,"十五":15,"十六":16,"十七":17,"十八":18,"十九":19}
def week_convert(s):
m = re.match(r"第(.+)周",s)
if m:
han = m.group(1)
num = chinese_num.get(han)
if num is not None:
return f"第{num}周"
return s
df["周次"] = df["周次"].apply(week_convert)
# =================【新版日期转换函数,长横杠替换为短横杠】=================
def convert_date_text(txt):
txt = txt.strip()
# 把中文长破折号全部替换为英文短横杠
txt = txt.replace("---", "-")
# 已经是区间格式直接返回
if "-" in txt and re.search(r"\d+/\d+-\d+/\d+", txt):
return txt
# 匹配 9月1日 格式
m_single = re.match(r"(\d+)月(\d+)日", txt)
if m_single:
mon, day = map(int, m_single.groups())
year = 2027 if mon == 1 else 2026
d_start = datetime(year, mon, day)
# 判断:9月1日(第一周)+3天;其他单日期+4天
if mon ==9 and day ==1:
delta = timedelta(days=3)
else:
delta = timedelta(days=4)
d_end = d_start + delta
# 输出格式 M/D-M/D 使用英文短横杠
s_start = f"{d_start.month}/{d_start.day}"
s_end = f"{d_end.month}/{d_end.day}"
return f"{s_start}-{s_end}"
return txt
df["时间"] = df["时间"].apply(convert_date_text)
# 班级格式化:兼容 中1 /中1班 /大1 /大1班 → 中(1)班 /大(1)班
def format_class_name(s):
s = str(s).strip()
if not s.endswith("班"):
s = s + "班"
return re.sub(r"(\D+)(\d+)(班)", r"\1(\2)\3", s)
df["班级"] = df["班级"].apply(format_class_name)
# 重命名列到英文标准:week,date,topic,leader,classroom
df.rename(columns={
"周次":"week",
"时间":"date",
"主题":"topic",
"行政老师":"leader",
"班级":"classroom"
}, inplace=True)
# garden列放第一列
df.insert(0, "garden", "总园")
# 新增空白辅助列,更新:s1‑s10
add_cols = ["teacher1","teacher2",
"s1","s2","s3","s4","s5","s6","s7","s8","s9","s10",
"sw1","sw2","sw3","sw4","sw5","tw"]
for col_name in add_cols:
df[col_name] = ""
# ==========读取老师名单==========
df_teacher = pd.read_excel(teacher_file)
teacher_dict = {}
for cls, group in df_teacher.groupby("班级"):
names = []
for _,r in group.iterrows():
nm = str(r["姓名"]).strip()
if pd.notna(nm) and nm!="":
names.append(nm)
t1 = names[0] if len(names)>=1 else ""
t2 = names[1] if len(names)>=2 else ""
teacher_dict[str(cls).strip()] = (t1, t2)
print("老师字典",teacher_dict)
# ==========读取多sheet学生名单==========
excel_file = pd.ExcelFile(stu_file)
all_sheet_names = excel_file.sheet_names
print(f"Excel全部工作表sheet:{all_sheet_names}")
class_student_dict = {}
for sheet_name in all_sheet_names:
df_sheet = pd.read_excel(stu_file, sheet_name=sheet_name)
cls_key = sheet_name.strip()
name_list = []
if "姓名" in df_sheet.columns:
for _, row in df_sheet.iterrows():
name = row["姓名"]
if pd.notna(name) and str(name).strip() != "":
name_list.append(str(name).strip())
class_student_dict[cls_key] = name_list
print("读取到班级字典key:", list(class_student_dict.keys()))
# 【重要】正则增加中、大,支持总园中班、大班
class_fuzzy_map = {}
for raw_key in class_student_dict.keys():
match_res = re.search(r"(托|小|中|大)(\d+)", raw_key)
if match_res:
prefix, num = match_res.groups()
class_fuzzy_map[(prefix, int(num))] = raw_key
class_pointer = {k:0 for k in class_student_dict.keys()}
s_col_list = ["s1","s2","s3","s4","s5","s6","s7","s8","s9","s10"]
def get_next_ten_by_display_name(display_name:str):
"""每次取10个学生,游标自动前进,列表循环"""
m = re.search(r"(托|小|中|大)[^\d]*(\d+)", display_name)
if not m:
print(f"⚠️无法解析班级:{display_name}")
return [""]*10
prefix, num = m.groups()
num = int(num)
fuzzy_key = (prefix, num)
if fuzzy_key not in class_fuzzy_map:
print(f"⚠️没有找到班级 {prefix}{num}")
return [""]*10
real_dict_key = class_fuzzy_map[fuzzy_key]
stu_list = class_student_dict[real_dict_key]
if len(stu_list)==0:
return [""]*10
ptr = class_pointer[real_dict_key]
out = []
total = len(stu_list)
while len(out) < 10:
idx = ptr % total
out.append(stu_list[idx])
ptr += 1
class_pointer[real_dict_key] = ptr
return out
# 逐行填充 teacher1 teacher2 + s1‑s10
for idx, row in df.iterrows():
disp_cls = row["classroom"]
m_cls = re.search(r"(托|小|中|大)[^\d]*(\d+)", disp_cls)
if m_cls:
pre, num = m_cls.groups()
cls_short = f"{pre}{num}"
t1,t2 = teacher_dict.get(cls_short, ("",""))
df.at[idx,"teacher1"] = t1
df.at[idx,"teacher2"] = t2
ten_names = get_next_ten_by_display_name(disp_cls)
for i,col in enumerate(s_col_list):
df.at[idx, col] = ten_names[i]
# ----------------------输出Excel----------------------
os.makedirs(out_dir, exist_ok=True)
df.to_excel(excel_out_path, index=False, engine="openpyxl")
# 列:garden week date topic leader classroom teacher1 teacher2 s1‑s10 sw1‑sw4 tw
col_widths = [12,
10, 25, 15, 15, 15,
12, 12,
10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,
10]
wb = load_workbook(excel_out_path)
ws = wb.active
for idx, width in enumerate(col_widths):
col_letter = get_column_letter(idx+1)
ws.column_dimensions[col_letter].width = width
wb.save(excel_out_path)
wb.close()
print(f"\n✅已生成:{excel_out_path}")
print(df[["garden","week","classroom","teacher1","teacher2","s1","s2","s3","s4","s5","s6","s7","s8","s9","s10"]].to_string())

虽然10个孩子,但是还是5个幼儿讲话

三、匹配文字
找到以前的关键词,复制最新的关键词

一分园AI文字:豆包
关键词:
我需要写一份小班发言的国旗下讲话,主题是"XXXX",一共五位孩子发言每人30字童趣化不要统一的字数、格式。再写一份老师讲话内容200字。表格形式呈现,只要讲话内容。不要小朋友和老师的字样。"XXXX"是下面的主题交通安全一盔一带
老师节日快乐
普通话推广周
爱眼护眼
喜迎国庆节
谨防电信诈骗
保护地球
我爱运动
珍惜粮食不浪费
消防安全月
预防传染病
劳动最光荣
爱护小动物
我会刷牙和漱口
交通安全
我爱老师和同伴
食品安全
迎接2027年
防拐防骗
(每个主题5位孩子说的话是5列展示,每列30字,第六列是教师发言250字,字不能太少)







Python批量写入

python
'''
一分园,国旗下讲话 把EXCLE模版内容写入WORD
豆包、Deepseek、阿夏
202609023
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
import numpy as np
import win32com.client as win32
# ========== 核心优化:路径处理 ==========
# 根路径(根据你的文件位置调整,建议用绝对路径)
path=r'D:\Python最终内容\20260906国旗下讲话'
root_path = path+r'\01一分园'
# 生成文档的临时文件夹
temp_folder = os.path.join(root_path, "202602一分园国旗下讲话模版")
os.makedirs(temp_folder, exist_ok=True)
# 存储生成的文件路径
generated_files = []
# ========== 1. 读取班级信息表和安排表 ==========
# 班级信息表路径
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
# 国旗下讲话安排表路径
schedule_path = os.path.join(root_path, "一分园.xlsx")
# 模板文件路径
template_path = os.path.join(path, "模版 分园.docx")
# 检查关键文件是否存在
if not os.path.exists(class_info_path):
print(f"错误:班级信息表不存在 - {class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"错误:安排表不存在 - {schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"错误:模板文件不存在 - {template_path}")
exit()
# 读取班级信息表(所有工作表)
class_info = pd.read_excel(class_info_path, sheet_name=None)
# 读取安排表
schedule = pd.read_excel(schedule_path)
# 确保s1-s5列是字符串类型,避免nan显示
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace('nan', '')
# ========== 2. 按班级+学号排序生成学生名单 ==========
class_students = {} # 班级: [学生姓名列表]
for sheet_name, df in class_info.items():
# 只处理含"班"的工作表,跳过模板表
if '班' in sheet_name and sheet_name not in ['模板']:
# 过滤空姓名 + 按学号升序排序
valid_df = df[df['姓名'].notna() & (df['姓名'] != '')].sort_values(by='学号', ascending=True)
students = valid_df['姓名'].tolist()
class_students[sheet_name] = students
print(f"✅ 班级 {sheet_name}: 共{len(students)}名学生")
# 班级索引跟踪器(记录每个班级下一组该取第几个学生)
class_index_tracker = {cls: 0 for cls in class_students.keys()}
# ========== 3. 填充安排表的s1-s5列 ==========
for index, row in schedule.iterrows():
classroom = str(row['classroom']).strip()
# 兼容班级名称格式(比如"小(1)班"转"小1班")
clean_classroom = classroom.replace('(', '').replace(')', '').replace('(', '').replace(')', '')
if clean_classroom in class_students:
students = class_students[clean_classroom]
current_idx = class_index_tracker[clean_classroom]
total_students = len(students)
# 确定每组人数:托班4人,小班5人
group_size = 4 if '托' in clean_classroom else 5
# 选取当前组学生(循环取,用完从头再来)
selected = []
for i in range(group_size):
selected.append(students[current_idx % total_students])
current_idx += 1
# 更新索引
class_index_tracker[clean_classroom] = current_idx
# 填充到s1-s5列(不足5人的补空)
for i in range(5):
col_name = f's{i+1}'
schedule.at[index, col_name] = selected[i] if i < len(selected) else ""
print(f"📌 第{index+1}行 {clean_classroom}: {selected}")
else:
print(f"⚠️ 未找到班级 {clean_classroom} 的学生信息")
# 保存填充后的安排表(覆盖原文件)
schedule.to_excel(schedule_path, index=False)
print(f"\n✅ 已保存填充后的安排表: {schedule_path}")
# ========== 4. 批量生成各班国旗下讲话文档 ==========
try:
# 验证模板文件是否有效
test_doc = Document(template_path)
print("✅ 模板文件验证通过,开始生成文档...")
except Exception as e:
print(f"❌ 模板文件无效: {e}")
exit()
for index, row in schedule.iterrows():
try:
# 每次重新加载模板,避免数据污染
tpl = DocxTemplate(template_path)
# 格式化班级名称(小1班 → 小(1)班)
classroom_str = str(row['classroom'])
if len(classroom_str) >= 3 and classroom_str[1].isdigit():
formatted_class = f"{classroom_str[0]}({classroom_str[1]}){classroom_str[2:]}"
else:
formatted_class = classroom_str
# 构建模板上下文(包含所有占位符)
context = {
"date": str(row['date']),
"week": str(row['week']),
"teacher1": str(row['teacher1']) if pd.notna(row['teacher1']) else "待定",
"teacher2": str(row['teacher2']) if pd.notna(row['teacher2']) else "待定",
"classroom": formatted_class,
"topic": str(row['topic']),
"leader": str(row['leader']),
# 幼儿姓名
"s1": str(row['s1']) if pd.notna(row['s1']) and row['s1'] != 'nan' else "",
"s2": str(row['s2']) if pd.notna(row['s2']) and row['s2'] != 'nan' else "",
"s3": str(row['s3']) if pd.notna(row['s3']) and row['s3'] != 'nan' else "",
"s4": str(row['s4']) if pd.notna(row['s4']) and row['s4'] != 'nan' else "",
"s5": str(row['s5']) if pd.notna(row['s5']) and row['s5'] != 'nan' else "",
# 幼儿讲话内容占位符(提示填写)
"sw1": str(row['sw1']),
"sw2": str(row['sw2']),
"sw3": str(row['sw3']),
"sw4": str(row['sw4']),
"sw5": str(row['sw5']),
# 老师讲话内容占位符
"tw": str(row['tw']),
}
# 渲染模板
tpl.render(context)
# 格式化周次(第2周 → 第02周,方便文件排序)
week_str = str(row['week']).replace('第', '').replace('周', '')
try:
week_formatted = f"第{int(week_str):02d}周"
except:
week_formatted = str(row['week'])
# 生成文件名
filename = f"{week_formatted}_一分园_{row['classroom']}_国旗下的讲话_({row['topic']}).docx"
file_full_path = os.path.join(temp_folder, filename)
# 保存文档
tpl.save(file_full_path)
generated_files.append(file_full_path)
print(f"✅ 生成文档: {filename}")
except Exception as e:
print(f"❌ 生成第{index+1}行文档失败: {str(e)}")
continue
print(f"\n📊 文档生成完成!共生成 {len(generated_files)} 个文档")
# ========== 5. 合并所有生成的文档 ==========
def merge_word_documents(files, output_path):
"""合并多个Word文档,清理空行,只保留分页符"""
if not files:
print("⚠️ 没有文档可合并")
return
try:
# 启动Word应用
word = win32.gencache.EnsureDispatch('Word.Application')
word.Visible = False
word.DisplayAlerts = False
# 打开第一个文档作为基础
merged_doc = word.Documents.Open(files[0])
selection = word.Selection
# 移动到文档末尾并清理空行
selection.EndKey(Unit=6) # wdStory = 6
clean_extra_empty_lines(selection)
# 合并其他文档
for i, file_path in enumerate(files[1:], 1):
if not os.path.exists(file_path):
print(f"⚠️ 文件不存在,跳过: {os.path.basename(file_path)}")
continue
print(f"🔗 合并第{i+1}个文档: {os.path.basename(file_path)}")
# 插入分页符
selection.InsertBreak(7) # wdPageBreak = 7
# 插入文档内容
selection.InsertFile(
FileName=file_path,
Range="",
ConfirmConversions=False,
Link=False,
Attachment=False
)
# 清理空行
selection.EndKey(Unit=6)
clean_extra_empty_lines(selection)
# 保存合并后的文档
merged_doc.SaveAs(output_path)
merged_doc.Close()
print(f"\n✅ 合并完成!保存路径: {output_path}")
except Exception as e:
print(f"❌ 合并文档失败: {str(e)}")
import traceback
traceback.print_exc()
finally:
# 关闭Word
try:
word.Quit(SaveChanges=0)
except:
pass
def clean_extra_empty_lines(selection):
"""清理光标前的空行(表格后的回车符)"""
for _ in range(10): # 最多检查10层,避免无限循环
if selection.MoveLeft(Unit=1, Count=1): # wdCharacter = 1
if selection.Paragraphs(1).Range.Text.strip() == "":
selection.Paragraphs(1).Range.Delete()
else:
break
else:
break
# 光标回到文档末尾
selection.EndKey(Unit=6)
selection.Collapse(0)
# 执行合并
if generated_files:
merge_output_path = os.path.join(root_path, "(在线填写)202602一分园国旗下讲话合并版.docx")
merge_word_documents(generated_files, merge_output_path)
else:
print("⚠️ 跳过合并步骤:无生成的文档")


python
'''
一分园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
202602023
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
import numpy as np
# ========== 核心优化:路径处理 ==========
dates="202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path+r'\01一分园'
temp_folder = os.path.join(paths, "01 (一分园)每周国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
class_merge_folder = os.path.join(paths, "02 (一分园)班级合并国旗下讲话")
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ========== 1. 读取班级信息表和安排表 ==========
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "一分园.xlsx")
template_path = os.path.join(path, "模版 分园.docx")
if not os.path.exists(class_info_path):
print(f"错误:班级信息表不存在 - {class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"错误:安排表不存在 - {schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"错误:模板文件不存在 - {template_path}")
exit()
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace('nan', '')
# ========== 2. 按班级+学号排序生成学生名单 ==========
class_students = {}
for sheet_name, df in class_info.items():
if '班' in sheet_name and sheet_name not in ['模板']:
valid_df = df[df['姓名'].notna() & (df['姓名'] != '')].sort_values(by='学号', ascending=True)
students = valid_df['姓名'].tolist()
class_students[sheet_name] = students
print(f"✅ 班级 {sheet_name}: 共{len(students)}名学生")
class_index_tracker = {cls: 0 for cls in class_students.keys()}
# ========== 3. 填充安排表的s1-s5列 ==========
for index, row in schedule.iterrows():
classroom = str(row['classroom']).strip()
clean_classroom = classroom.replace('(', '').replace(')', '').replace('(', '').replace(')', '')
if clean_classroom in class_students:
students = class_students[clean_classroom]
current_idx = class_index_tracker[clean_classroom]
total_students = len(students)
if '托' in clean_classroom:
group_size = 4
else:
group_size = 5
selected = []
for i in range(group_size):
selected.append(students[current_idx % total_students])
current_idx += 1
class_index_tracker[clean_classroom] = current_idx
for i in range(5):
col_name = f's{i+1}'
schedule.at[index, col_name] = selected[i] if i < len(selected) else ""
print(f"📌 第{index+1}行 {clean_classroom}: {selected}")
else:
print(f"⚠️ 未找到班级 {clean_classroom} 的学生信息")
schedule.to_excel(schedule_path, index=False)
print(f"\n✅ 已保存填充后的安排表: {schedule_path}")
# ========== 4. 批量生成各班国旗下讲话文档 ==========
class_documents = {}
doc_teachers = {}
try:
test_doc = Document(template_path)
print("✅ 模板文件验证通过,开始生成文档...")
except Exception as e:
print(f"❌ 模板文件无效: {e}")
exit()
for index, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
original_classroom = str(row['classroom']).strip()
classroom_str = original_classroom
if len(classroom_str) >= 3 and classroom_str[1].isdigit():
formatted_class = f"{classroom_str[0]}({classroom_str[1]}){classroom_str[2:]}"
else:
formatted_class = classroom_str
t1 = str(row['teacher1']) if pd.notna(row['teacher1']) else ""
t2 = str(row['teacher2']) if pd.notna(row['teacher2']) else ""
context = {
"date": str(row['date']) if pd.notna(row['date']) else "",
"week": str(row['week']) if pd.notna(row['week']) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": formatted_class,
"topic": str(row['topic']) if pd.notna(row['topic']) else "",
"leader": str(row['leader']) if pd.notna(row['leader']) else "",
"garden": "一分园",
"s1": str(row['s1']) if pd.notna(row['s1']) and row['s1'] != 'nan' else "",
"s2": str(row['s2']) if pd.notna(row['s2']) and row['s2'] != 'nan' else "",
"s3": str(row['s3']) if pd.notna(row['s3']) and row['s3'] != 'nan' else "",
"s4": str(row['s4']) if pd.notna(row['s4']) and row['s4'] != 'nan' else "",
"s5": str(row['s5']) if pd.notna(row['s5']) and row['s5'] != 'nan' else "",
"sw1": str(row['sw1']) if pd.notna(row['sw1']) else "",
"sw2": str(row['sw2']) if pd.notna(row['sw2']) else "",
"sw3": str(row['sw3']) if pd.notna(row['sw3']) else "",
"sw4": str(row['sw4']) if pd.notna(row['sw4']) else "",
"sw5": str(row['sw5']) if pd.notna(row['sw5']) else "",
"tw": str(row['tw']) if pd.notna(row['tw']) else "",
}
tpl.render(context)
week_str = str(row['week']).replace('第', '').replace('周', '')
try:
week_formatted = f"第{int(week_str):02d}周"
except:
week_formatted = str(row['week'])
filename = f"{week_formatted}_一分园_{row['classroom']}_国旗下的讲话_({row['topic']}).docx"
file_full_path = os.path.join(temp_folder, filename)
tpl.save(file_full_path)
generated_files.append(file_full_path)
doc_teachers[file_full_path] = (t1, t2)
if original_classroom not in class_documents:
class_documents[original_classroom] = []
class_documents[original_classroom].append(file_full_path)
print(f"✅ 生成文档: {filename}")
except Exception as e:
print(f"❌ 生成第{index+1}行文档失败: {str(e)}")
continue
print(f"\n📊 文档生成完成!共生成 {len(generated_files)} 个文档")
# ======================【合并函数:彻底删除rFonts东亚字体操作,规避None报错】======================
def merge_docx_pure(file_list, output_file):
if not file_list:
print("⚠️ 待合并文件列表为空")
return None
base_doc = Document(file_list[0])
for fpath in file_list[1:]:
if not os.path.exists(fpath):
print(f"⚠️ 文件跳过:{os.path.basename(fpath)}")
continue
sub_doc = Document(fpath)
base_doc.add_page_break()
# 复制段落,移除底层xml字体操作,只复制文字、字号
for para in sub_doc.paragraphs:
new_p = base_doc.add_paragraph()
new_p.alignment = para.alignment
for run in para.runs:
new_run = new_p.add_run(run.text)
new_run.font.size = run.font.size
# 做None判断,字体不为空才赋值
if run.font.name is not None:
new_run.font.name = run.font.name
# 复制表格(仅复制文本,边框样式会丢失,属于python‑docx限制)
for tbl in sub_doc.tables:
new_table = base_doc.add_table(rows=len(tbl.rows), cols=len(tbl.columns))
new_table.style = tbl.style
for r_idx, row in enumerate(tbl.rows):
for c_idx, cell in enumerate(row.cells):
new_table.cell(r_idx, c_idx).text = cell.text
base_doc.save(output_file)
print(f"✅ 合并完成输出:{output_file}")
return output_file
# ========== 5.按班级合并文档 ==========
print("\n" + "="*60)
print("开始按班级合并文档...")
print("="*60)
class_merge_files = []
for class_name, doc_files in class_documents.items():
if doc_files:
print(f"\n📁 处理班级: {class_name},共{len(doc_files)}个文档")
def get_week_number(filepath):
try:
filename = os.path.basename(filepath)
week_part = filename.split('_')[0]
week_num = week_part.replace('第', '').replace('周', '')
return int(week_num)
except:
return 999
sorted_docs = sorted(doc_files, key=get_week_number)
first_doc = sorted_docs[0]
t1, t2 = doc_teachers[first_doc]
teacher_name = "、".join([x for x in [t1, t2] if x.strip()])
if not teacher_name.strip():
teacher_name = "未指定教师"
teacher_name_clean = teacher_name.replace(' ', '').replace('/', '').replace('\\', '').replace(':', '').replace(':', '')
teacher_name_clean = teacher_name_clean.replace('、', '_').replace('·', '_').replace('•', '_')
output_filename = f"一分园_{class_name}__国旗下讲话汇总_{teacher_name_clean}_{dates}.docx"
output_path = os.path.join(class_merge_folder, output_filename)
merged = merge_docx_pure(sorted_docs, output_path)
if merged:
class_merge_files.append(merged)
print(f"\n✅ 按班级合并完成!共合并 {len(class_merge_files)} 个班级文档")
# ==========6.全部文档总合并==========
if generated_files:
print("\n" + "="*60)
print("开始生成总合并文档...")
print("="*60)
def get_week_number_all(filepath):
try:
filename = os.path.basename(filepath)
week_part = filename.split('_')[0]
week_num = week_part.replace('第', '').replace('周', '')
return int(week_num)
except:
return 999
def get_class_name(filepath):
try:
filename = os.path.basename(filepath)
parts = filename.split('_')
if len(parts)>=3:
return parts[2]
return filename
except:
return filename
sorted_files = sorted(generated_files, key=lambda x: (get_week_number_all(x), get_class_name(x)))
merge_output_path = os.path.join(class_merge_folder, "(03(在线填写)202602一分园国旗下讲话合并版).docx")
merge_docx_pure(sorted_files, merge_output_path)
print("\n" + "="*60)
print("程序执行完成!")
print(f"📂 单个文档:{temp_folder}")
print(f"📂 班级合并文档:{class_merge_folder}")
print("="*60)



python
'''
一分园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\01一分园'
temp_folder = os.path.join(paths, "01 (一分园)每周国旗下讲话")
class_merge_folder = os.path.join(paths, "02 (一分园)班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "一分园.xlsx")
template_path = os.path.join(path, "模版 分园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "一分园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_一分园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"一分园_{cls_name}_国旗下讲话_{tea}_{dates}.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_一分园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)




(二)二分园文本合成(豆包),不要写的和一分园deepseek一模一样
关键词:
我需要写一份小班发言的国旗下讲话,主题是"XXXX",一共五位孩子发言每人30字童趣化不要统一的字数、格式。再写一份老师讲话内容200字。表格形式呈现,只要讲话内容。不要小朋友和老师的字样。"XXXX"是下面的主题交通安全一盔一带
老师节日快乐
普通话推广周
爱眼护眼
喜迎国庆节
谨防电信诈骗
保护地球
我爱运动
珍惜粮食不浪费
消防安全月
预防传染病
劳动最光荣
爱护小动物
我会刷牙和漱口
交通安全
我爱老师和同伴
食品安全
迎接2027年
防拐防骗
(每个主题5位孩子说的话是5列展示,每列30字,第六列是教师发言250字,字不能太少)










把一分园导入word的代码修改参数


python
'''
二分园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\02二分园'
temp_folder = os.path.join(paths, "01 (二分园)每周国旗下讲话")
class_merge_folder = os.path.join(paths, "02 (二分园)班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "二分园.xlsx")
template_path = os.path.join(path, "模版 分园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "二分园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_二分园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"二分园_{cls_name}_国旗下讲话_{tea}_{dates}.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_二分园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)





(三)总园文本
键词:
我需要写一份中班大班发言的国旗下讲话,主题是"XXXX",一共五位孩子发言每人100字童趣化不要统一的字数、格式。再写一份老师讲话内容500字。表格形式呈现,只要讲话内容。不要小朋友和老师的字样。"XXXX"是下面的主题
交通安全一盔一带
老师节日快乐
普通话推广周
爱眼护眼
喜迎国庆节
谨防电信诈骗
保护地球
我爱运动
珍惜粮食不浪费
消防安全月
预防传染病
劳动最光荣
爱护小动物
我会刷牙和漱口
交通安全
我爱老师和同伴
食品安全
迎接2027年
防拐防骗
(每个主题5位孩子说的话是5列展示,每列100字,第六列是教师发言500字,字不能太少)
拆成两份,以免字数太多生成不了
第一份
我需要写一份中班大班发言的国旗下讲话,主题是"XXXX",一共五位孩子发言每人100字童趣化不要统一的字数、格式。再写一份老师讲话内容500字。表格形式呈现,只要讲话内容。不要小朋友和老师的字样。"XXXX"是下面的主题
交通安全一盔一带
老师节日快乐
普通话推广周
爱眼护眼
喜迎国庆节
谨防电信诈骗
保护地球
我爱运动
珍惜粮食不浪费
(每个主题5位孩子说的话是5列展示,每列100字,第六列是教师发言500字,字不能太少)
第二份
我需要写一份中班大班发言的国旗下讲话,主题是"XXXX",一共五位孩子发言每人100字童趣化不要统一的字数、格式。再写一份老师讲话内容500字。表格形式呈现,只要讲话内容。不要小朋友和老师的字样。"XXXX"是下面的主题
消防安全月
预防传染病
劳动最光荣
爱护小动物
我会刷牙和漱口
交通安全
我爱老师和同伴
食品安全
迎接2027年
防拐防骗
(每个主题5位孩子说的话是5列展示,每列100字,第六列是教师发言500字,字不能太少)
















总园要用总园的docx模版



要抄送10个孩子、5段发言。
''
python
'''
总园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\03总园'
temp_folder = os.path.join(paths, "01 (总园)每周国旗下讲话")
# class_merge_folder = os.path.join(paths, "02 (总园)班级合并国旗下讲话")
class_merge_folder = os.path.join(path, "00 发送全部班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "总园.xlsx")
template_path = os.path.join(path, "模版 总园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5','s6', 's7', 's8', 's9', 's10']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "总园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"s6": str(row["s6"]),
"s7": str(row["s7"]),
"s8": str(row["s8"]),
"s9": str(row["s9"]),
"s10": str(row["s10"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_总园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"{cls_name}_国旗下讲话_{tea}_{dates}_总园.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_总园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)



(四)发送文件合并到同一个文件夹下。
本来三个园区的合并国旗下docx分布在三个园区内,为了便于程序自动发送,需要合并到同一个文件夹下




我再顶部的代码贴好了
python
'''
一分园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\01一分园'
temp_folder = os.path.join(paths, "01 (一分园)每周国旗下讲话")
# class_merge_folder = os.path.join(paths, "02 (一分园)班级合并国旗下讲话")
class_merge_folder = os.path.join(path, "00 发送全部班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "一分园.xlsx")
template_path = os.path.join(path, "模版 分园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "一分园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_一分园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"{cls_name}_国旗下讲话_{tea}_{dates}_一分园.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_一分园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)
python
'''
二分园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\02二分园'
temp_folder = os.path.join(paths, "01 (二分园)每周国旗下讲话")
# class_merge_folder = os.path.join(paths, "02 (二分园)班级合并国旗下讲话")
class_merge_folder = os.path.join(path, "00 发送全部班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "二分园.xlsx")
template_path = os.path.join(path, "模版 分园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "二分园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_二分园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"{cls_name}_国旗下讲话_{tea}_{dates}_二分园.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_二分园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)
python
'''
总园,国旗下讲话 把EXCLE模版内容写入WORD(文本占位符),合并保存一份,按班级保存一份
豆包、Deepseek、阿夏
20260827
'''
import pandas as pd
from docxtpl import DocxTemplate
import os
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# ==================== 基础配置 ====================
dates = "202609"
path = r'D:\Python最终内容\20260906国旗下讲话'
paths = path + r'\03总园'
temp_folder = os.path.join(paths, "01 (总园)每周国旗下讲话")
# class_merge_folder = os.path.join(paths, "02 (总园)班级合并国旗下讲话")
class_merge_folder = os.path.join(path, "00 发送全部班级合并国旗下讲话")
os.makedirs(temp_folder, exist_ok=True)
os.makedirs(class_merge_folder, exist_ok=True)
generated_files = []
# ==================== 文件路径 ====================
class_info_path = os.path.join(path, "01 20260805班级信息表.xlsx")
schedule_path = os.path.join(paths, "总园.xlsx")
template_path = os.path.join(path, "模版 总园.docx")
if not os.path.exists(class_info_path):
print(f"缺失:{class_info_path}")
exit()
if not os.path.exists(schedule_path):
print(f"缺失:{schedule_path}")
exit()
if not os.path.exists(template_path):
print(f"缺失:{template_path}")
exit()
# 读取表格
class_info = pd.read_excel(class_info_path, sheet_name=None)
schedule = pd.read_excel(schedule_path)
# 清空nan
for col in ['s1', 's2', 's3', 's4', 's5','s6', 's7', 's8', 's9', 's10']:
if col in schedule.columns:
schedule[col] = schedule[col].astype(str).replace("nan", "")
# ==================== 读取各班学生 ====================
class_students = {}
for sheet_name, df in class_info.items():
if "班" in sheet_name and sheet_name != "模板":
df_valid = df.dropna(subset=["姓名"])
df_valid = df_valid[df_valid["姓名"] != ""]
df_valid = df_valid.sort_values("学号")
stu_list = df_valid["姓名"].tolist()
class_students[sheet_name] = stu_list
print(f"✅ {sheet_name}:{len(stu_list)}人")
class_index_tracker = {k: 0 for k in class_students.keys()}
# ==================== 自动填充 s1‑s5 学生 ====================
for idx, row in schedule.iterrows():
raw_class = str(row["classroom"]).strip()
clean_class = raw_class.replace("(","").replace(")","").replace("(","").replace(")","")
if clean_class not in class_students:
print(f"⚠️ 无班级:{raw_class}")
continue
stu_list = class_students[clean_class]
now_idx = class_index_tracker[clean_class]
total = len(stu_list)
size = 5
select_stu = []
for i in range(size):
select_stu.append(stu_list[now_idx % total])
now_idx += 1
class_index_tracker[clean_class] = now_idx
for i in range(5):
col = f"s{i+1}"
schedule.at[idx, col] = select_stu[i] if i < len(select_stu) else ""
print(f"📌 {raw_class} → {select_stu}")
schedule.to_excel(schedule_path, index=False)
print("✅ 学生名单填充完成并保存表格!")
# ==================== 单周文档生成 ====================
class_documents = {}
doc_teachers = {}
try:
Document(template_path)
print("✅ 模板正常")
except:
print("❌ 模板损坏!")
exit()
for idx, row in schedule.iterrows():
try:
tpl = DocxTemplate(template_path)
raw_class = str(row["classroom"]).strip()
if len(raw_class) >= 3 and raw_class[1].isdigit():
fmt_class = f"{raw_class[0]}({raw_class[1]}){raw_class[2:]}"
else:
fmt_class = raw_class
t1 = str(row["teacher1"]) if pd.notna(row["teacher1"]) else ""
t2 = str(row["teacher2"]) if pd.notna(row["teacher2"]) else ""
context = {
"date": str(row["date"]) if pd.notna(row["date"]) else "",
"week": str(row["week"]) if pd.notna(row["week"]) else "",
"teacher1": t1,
"teacher2": t2,
"classroom": fmt_class,
"topic": str(row["topic"]) if pd.notna(row["topic"]) else "",
"leader": str(row["leader"]) if pd.notna(row["leader"]) else "",
"garden": "总园",
"s1": str(row["s1"]),
"s2": str(row["s2"]),
"s3": str(row["s3"]),
"s4": str(row["s4"]),
"s5": str(row["s5"]),
"s6": str(row["s6"]),
"s7": str(row["s7"]),
"s8": str(row["s8"]),
"s9": str(row["s9"]),
"s10": str(row["s10"]),
"sw1": str(row["sw1"]) if pd.notna(row["sw1"]) else "",
"sw2": str(row["sw2"]) if pd.notna(row["sw2"]) else "",
"sw3": str(row["sw3"]) if pd.notna(row["sw3"]) else "",
"sw4": str(row["sw4"]) if pd.notna(row["sw4"]) else "",
"sw5": str(row["sw5"]) if pd.notna(row["sw5"]) else "",
"tw": str(row["tw"]) if pd.notna(row["tw"]) else "",
}
tpl.render(context)
week_str = str(row["week"]).replace("第","").replace("周","")
try:
week_fmt = f"第{int(week_str):02d}周"
except:
week_fmt = str(row["week"])
filename = f"{week_fmt}_总园_{raw_class}_国旗下的讲话_({row['topic']}).docx"
full_path = os.path.join(temp_folder, filename)
tpl.save(full_path)
# =====【关键】单文件阶段,给标题强制设置段后间距,不靠空回车段落 =====
tmp_doc = Document(full_path)
for para in tmp_doc.paragraphs:
if para.text.strip() == "国旗下的讲话":
para.paragraph_format.space_after = Pt(1)
break
tmp_doc.save(full_path)
# ==========================================================
generated_files.append(full_path)
doc_teachers[full_path] = (t1, t2)
if raw_class not in class_documents:
class_documents[raw_class] = []
class_documents[raw_class].append(full_path)
print(f"✅ 生成:{filename}")
except Exception as e:
print(f"❌ 第{idx+1}行失败:{e}")
print(f"\n📊 共生成 {len(generated_files)} 个单独文档")
# ==============================================
# 合并函数:第一个文件做基底,保留完整styles样式,字体不乱;先分页,再贴子文档
# ==============================================
def merge_perfect(file_list, out_path):
if not file_list:
return
# 以第一个文件作为主文档,保留完整styles.xml,字体、表格样式全部保留,不会乱码
main = Document(file_list[0])
main_body = main._element.body
def insert_page_break(body):
p = OxmlElement("w:p")
r = OxmlElement("w:r")
br = OxmlElement("w:br")
br.set(qn('w:type'), "page")
r.append(br)
p.append(r)
body.append(p)
# 从第2个开始循环
for file in file_list[1:]:
sub = Document(file)
sub_body = sub._element.body
# 先插入分页符,再追加子文档全部内容
insert_page_break(main_body)
for child in sub_body:
main_body.append(child)
main.save(out_path)
print(f"✅ 合并完成:{os.path.basename(out_path)}")
# ==================== 按班级合并 ====================
print("\n========== 开始班级合并 ==========")
for cls_name, file_list in class_documents.items():
def get_week(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
file_sorted = sorted(file_list, key=get_week)
first_file = file_sorted[0]
t1,t2 = doc_teachers[first_file]
tea = "、".join([x for x in [t1,t2] if x.strip()]) or "无"
tea = tea.replace("、","_").replace(" ","")
out_name = f"{cls_name}_国旗下讲话_{tea}_{dates}_总园.docx"
out_path = os.path.join(class_merge_folder, out_name)
merge_perfect(file_sorted, out_path)
# ==================== 全部总合并 ====================
if generated_files:
def week_key(p):
try:
return int(os.path.basename(p).split("_")[0].replace("第","").replace("周",""))
except:
return 999
all_sort = sorted(generated_files, key=week_key)
total_out = os.path.join(class_merge_folder, "03_总园国旗下讲话总合并文档.docx")
merge_perfect(all_sort, total_out)
print("\n🎉🎉🎉 全部完成!格式不乱、分页统一!")
print("单文档文件夹:", temp_folder)
print("合并文档文件夹:", class_merge_folder)
19个班级都合并在一个文件夹下
六、发送
(一)调整代码
复制"开学资料打包RAR"里面的发送.py



测试发送时,发送每个word文件里面有"园区",班级和教师姓名,根本无法统一文件名。只是输入班级(她不在索引0的位置,在索引1的位置),无法匹配到正确的word文件

如果我把班级放在文件名的索引0,(第一个),输入班级文字,会匹配到唯一一个docx。

所以在写入word代码里面,修改文件名中"园区"的位置,把它放到最后面,班级放在第一位"



现在合并docx的文件夹合集里面的word都是以"班级"为起始





(二)正式发送班主任





提示文字更改
title = f'尊敬的{name}老师:\n\n 20260228 {classesi}班 \n2026学年第一学期(2026年9月)国旗下讲话(有文字版)\n\n请马上微信收藏、到学期结束再用\n贴照片,删除几行文字,确保都在一页或两页内)。'
python
'''
微信放大整个页面,重新选择抄图按钮
选择班级对应的两位班主任,私发给班主任个人
发送国旗下讲话docx
Deepseek,阿夏
20260919
'''
import pandas as pd
import os
from pathlib import Path
import pyautogui
import time
import pyperclip
import re
import win32api
import win32con
import sys
import ctypes
import pygetwindow as gw
import random
# 1. 找到VSCode窗口(匹配标题含 Visual Studio Code)
vscode_wins = gw.getWindowsWithTitle("Visual Studio Code")
win = None
if not vscode_wins:
print("未找到VSCode窗口,请先打开VSCode再运行!")
else:
win = vscode_wins[0]
# 自动最小化VSCode
win.minimize()
print("VSCode已自动最小化,你有5秒时间移动鼠标到目标位置")
time.sleep(5) # 等待5秒给你放鼠标
# 读取名单
import openpyxl
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
# 读取Excel文件
paths=r'D:\Python最终内容\20260906国旗下讲话'
path = paths+r'\00 发送全部班级合并国旗下讲话'
file_path = paths + r'\03 微信发送名单.xlsx'
df = pd.read_excel(file_path, sheet_name=0) # 读取第一张工作表
# 获取班级和姓名列(假设第一列是班级,第二列是姓名)
classes = df.iloc[:, 0].tolist() # 第一列
names = df.iloc[:, 1].tolist() # 第二列
print(classes)
print(names)
# 生成3‑5秒随机延时
def rand_sleep():
t = random.uniform(3.0, 5.0)
time.sleep(t)
# ============新增:根据excel班级名匹配docx文件============
def find_target_docx(base_dir: str, excel_class_text: str):
res = re.match(r"([大托小])(\d+)", str(excel_class_text).strip())
if not res:
print(f"⚠班级格式无法解析:{excel_class_text}")
return None
prefix, num = res.groups()
search_key = f"{prefix}({num})班"
dir_obj = Path(base_dir)
all_docx = list(dir_obj.glob("*.docx"))
for f in all_docx:
if search_key in f.name:
print(f"✅匹配到docx: {f.name}")
return str(f)
print(f"❌未找到包含【{search_key}】的docx")
return None
def send_wechat_file(file_fullpath):
"""发送微信文件,请修改下面坐标为你微信附件📎按钮真实屏幕坐标"""
file_button_x, file_button_y = 817, 738
pyautogui.moveTo(file_button_x, file_button_y)
pyautogui.click()
rand_sleep()
pyperclip.copy(file_fullpath)
pyautogui.hotkey("ctrl", "v")
rand_sleep()
pyautogui.press("enter")
rand_sleep()
pyautogui.moveTo(1844, 974)
pyautogui.click()
rand_sleep()
# =========================================================
txt_path = path + r'\00 发送全部班级合并国旗下讲话'
for i in range(4, len(classes)):
# if classes[i]=='小2':
name = names[i]
print(name)
txt = f'{classes[i][0]}({classes[i][1]})班'
# 查找对应班级docx
docx_file = find_target_docx(path, classes[i])
# --------------下面全部是你原来的原始代码,无修改----------------
# 点击微信的姓名输入框
pyautogui.moveTo(142, 65)
pyautogui.click()
rand_sleep()
# 输入姓名
pyperclip.copy(name)
# 黏贴班级名称
pyautogui.hotkey('ctrl', 'v')
rand_sleep()
#点击名字
pyautogui.moveTo(176, 159)
pyautogui.click()
rand_sleep()
#选择文件(文件按钮)每次需要重新选择
pyautogui.moveTo(503,975)
pyautogui.click()
rand_sleep()
# 复制路径
pyperclip.copy(txt)
# 黏贴班级名称
pyautogui.hotkey('ctrl', 'v')
rand_sleep()
# 选择大1班 XXXX的文件(每次都要重新测算)
pyautogui.moveTo(407,541)
pyautogui.click()
rand_sleep()
# 模拟按下Enter键
pyautogui.press('enter')
rand_sleep()
#点击输入框写入第一个说明
pyautogui.moveTo(540, 735)
pyautogui.click()
rand_sleep()
# 说明文字
title = f'尊敬的{name}老师:\n\n 20260228 {classes[i]}班 \n2026学年第一学期(2026年9月)国旗下讲话(有文字版)\n\n请马上微信收藏、到学期结束再用\n贴照片,删除几行文字,确保都在一页或两页内)。'
# 黏贴说明文字
pyperclip.copy(title)
# 黏贴班级名称
pyautogui.hotkey('ctrl', 'v')
rand_sleep()
# 模拟按下Enter键
pyautogui.press('enter')
# ========================================================
# 自动最大化VSCode
if win is not None:
win.maximize()
print("VSCode已自动最大化,程序结束")
39人,一共发了30分钟,很慢很慢,但是没有出现微信关闭

电脑微信上最后的效果


手机上的效果


自己也备份,收藏




人手一份,群众反馈












