【办公类-146-07】20260906《总园大班6个班级四大教育》(优化版:标题excle+复制AI文字+Python占位符录入)

一、背景需求

20260909收到总园大班的四大教育内容

大班和中班的word模版一样

那么参考中班的已有四大教育模式,做一份大班的四大教育

【办公类-146-06】20260906《总园中班6个班级四大教育》(优化版:标题excle+复制AI文字+Python占位符录入)https://mp.csdn.net/mp_blog/creation/editor/164478585

二、word模版修改

复制中班的模版。

三、制作标题

python 复制代码
'''
总园大班四大教育4个主题,每个主题4个 共16个 - 完整工作流
1. 生成占位符Excel
2. 根据Excel生成Word文档
3. 处理Word文档(aaa转手动换行符、空格缩进)
4. 打包成RAR
豆包、Deepseek、阿夏
20260910
'''
import pandas as pd
import os

# ========== 路径配置 ==========
BASE_PATH = r'D:\Python最终内容\20260906四大教育\总园\总园大班四大教育'
CLASS_NAME = "总园大班"
EDU_THEME = "全部主题"
date='20260909'

EXCEL_PATH = os.path.join(BASE_PATH, f"{date}{CLASS_NAME}四大教育({EDU_THEME}).xlsx")

# 表头字段(和生成word脚本完全对齐)
columns = [
    'garden','name0','name1','grade','name2',
    'year', 'month', 'topic', 'goal', 
    'procedure', 'reflection','ts',
]

def create_empty_excel_header_only():
    """只生成仅有表头的Excel,没有数据行"""
    os.makedirs(BASE_PATH, exist_ok=True)
    df = pd.DataFrame(columns=columns)
    df.to_excel(EXCEL_PATH, index=False)
    print(f"✅ 已生成仅带表头的Excel")
    print(f"📂 文件路径:{EXCEL_PATH}")
    print(f"📋 表头:{columns}")

if __name__ == "__main__":
    create_empty_excel_header_only()

三、deepseek豆包AI文字

只有四个计划表,没有模版,所以我从总园中班里面找了一个爱国教育1月的模版,把中班改成大班

把计划书内容修改到这个模版里

活动主题里面的主标题,副标题修改

再做一个模版,便于deepseek理解。

五、EXCEL写入word

python 复制代码
'''
大班四大教育4个主题,每个主题4个 共20个 - 完整工作流
1. 生成占位符Excel
2. 根据Excel生成Word文档
3. 处理Word文档(aaa转手动换行符、空格缩进)
4. 打包成RAR
豆包、Deepseek、阿夏
20260909
'''

import pandas as pd
from docxtpl import DocxTemplate
from docx import Document
from docx.enum.text import WD_BREAK
from docx.shared import Pt
from docx.oxml.ns import qn
import os
import sys
import subprocess
import zipfile
import shutil

# ========== 全局路径配置(只需修改这里) ==========
# 根路径 - 所有文件都基于这个路径
BASE_PATH = r'D:\Python最终内容\20260906四大教育\总园\总园大班四大教育'
# 班级名称

CLASS_NAME = "总园大班"
# 教育主题
EDU_THEME = "全部主题"

date='20260909'
# ==============================================

# 根据基础路径生成所有子路径
EXCEL_PATH = os.path.join(BASE_PATH, f"{date}{CLASS_NAME}四大教育({EDU_THEME}).xlsx")
TEMPLATE_PATH = os.path.join(BASE_PATH, f"01 {CLASS_NAME}四大教育模版.docx")
OUTPUT_FOLDER = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})四大教育_{EDU_THEME}")
PROCESSED_FOLDER = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})四大教育_{EDU_THEME}最终")
RAR_PATH = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})四大教育_{EDU_THEME}最终.rar")
ZIP_PATH = os.path.join(BASE_PATH, f"01 ({CLASS_NAME})四大教育_{EDU_THEME}最终.zip")

# 设置控制台编码
if sys.platform == 'win32':
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# def step1_generate_excel():
#     """第一步:生成占位符Excel文件"""
#     print("\n" + "="*60)
#     print("第一步:生成占位符Excel文件")
#     print("="*60)
    
#     # 创建数据框
#     df = pd.DataFrame(columns=[
#         'garden','name0','name1','grade','name2','year', 'month', 'topic', 'goal', 'procedure', 'reflection','ts',
#     ])
    
#     # 保存为Excel文件
#     df.to_excel(EXCEL_PATH, index=False)
    
#     print(f"✅ Excel文件已生成:{EXCEL_PATH}")
#     input('\n请先在Excel中填入AI生成的内容,然后按回车键继续...')
#     return True

def step2_generate_word_from_excel():
    """第二步:根据Excel生成Word文档"""
    print("\n" + "="*60)
    print("第二步:根据Excel生成Word文档")
    print("="*60)
    
    # 创建输出文件夹
    os.makedirs(OUTPUT_FOLDER, exist_ok=True)
    
    # 存储生成的文件路径
    generated_files = []
    
    # 检查关键文件是否存在
    if not os.path.exists(EXCEL_PATH):
        print(f"❌ 错误:安排表不存在 - {EXCEL_PATH}")
        return False
    if not os.path.exists(TEMPLATE_PATH):
        print(f"❌ 错误:模板文件不存在 - {TEMPLATE_PATH}")
        return False
    
    # 读取安排表
    schedule = pd.read_excel(EXCEL_PATH)
    
    # 确保列是字符串类型,避免nan显示
    new_columns = ['garden','name0','name1','grade','name2','year', 'month', 'topic', 'goal', 'procedure', 'reflection', 'classroom', 'teachers','ts']
    for col in new_columns:
        if col in schedule.columns:
            schedule[col] = schedule[col].astype(str).replace('nan', '')
    
    # 设置默认值
    if 'year' not in schedule.columns:
        schedule['year'] = '2026'
    if 'month' not in schedule.columns:
        schedule['month'] = '3'
    if 'garden' not in schedule.columns:
        schedule['garden'] = '大班'
    if 'classroom' not in schedule.columns:
        schedule['classroom'] = CLASS_NAME
    if 'teachers' not in schedule.columns:
        schedule['teachers'] = '待定'
    
    # 保存安排表(覆盖原文件)
    schedule.to_excel(EXCEL_PATH, index=False)
    print(f"✅ 已保存安排表")
    print(f"📊 安排表共有 {len(schedule)} 行数据")
    
    # 验证模板文件
    try:
        test_doc = Document(TEMPLATE_PATH)
        print("✅ 模板文件验证通过,开始生成文档...")
    except Exception as e:
        print(f"❌ 模板文件无效: {e}")
        return False
    
    # 批量生成文档
    for index, row in schedule.iterrows():
        try:
            tpl = DocxTemplate(TEMPLATE_PATH)
            
            # 获取班级名
            classroom = str(row['classroom']) if pd.notna(row['classroom']) else CLASS_NAME
            original_classroom = 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:]}"
            elif '(' in classroom_str or '(' in classroom_str:
                formatted_class = classroom_str
            else:
                formatted_class = classroom_str
            
            # 获取教师姓名
            teacher_name = str(row['teachers']) if pd.notna(row['teachers']) and str(row['teachers']) != 'nan' else "待定"
            
            # 构建模板上下文
            context = {
                "grade": str(row['grade']) if pd.notna(row['grade']) and str(row['grade']) != 'nan' else '',             
                "name0": str(row['name0']) if pd.notna(row['name0']) and str(row['name0']) != 'nan' else '',
                "name1": str(row['name1']) if pd.notna(row['name1']) and str(row['name1']) != 'nan' else '',
                "name2": str(row['name2']) if pd.notna(row['name2']) and str(row['name2']) != 'nan' else '',
                "year": str(row['year']) if pd.notna(row['year']) and str(row['year']) != 'nan' else '2026',
                "month": str(row['month']) if pd.notna(row['month']) and str(row['month']) != 'nan' else '3',
                "garden": str(row['garden']) if pd.notna(row['garden']) and str(row['garden']) != 'nan' else '大班',
                "topic": str(row['topic']) if pd.notna(row['topic']) and str(row['topic']) != 'nan' else '',
                "goal": str(row['goal']) if pd.notna(row['goal']) and str(row['goal']) != 'nan' else '',
                "procedure": str(row['procedure']) if pd.notna(row['procedure']) and str(row['procedure']) != 'nan' else '',
                "reflection": str(row['reflection']) if pd.notna(row['reflection']) and str(row['reflection']) != 'nan' else '',
                "classroom": formatted_class,
                "teachers": teacher_name,
                "date": str(row['date']) if 'date' in row and pd.notna(row['date']) else '',
                "week": str(row['week']) if 'week' in row and pd.notna(row['week']) else '',
                "leader": str(row['leader']) if 'leader' in row and pd.notna(row['leader']) else '',
                "ts": str(row['ts']) if 'ts' in row and pd.notna(row['ts']) else '',
            }
            
            # 渲染模板
            tpl.render(context)
            
            # 保存文档到临时文件
            temp_path = os.path.join(OUTPUT_FOLDER, f"temp_{index}.docx")
            tpl.save(temp_path)
            
            # 打开文档进行样式修复
            doc = Document(temp_path)
            
            # 修复反思部分的字体大小(确保是小四12磅)
            modified = False
            if doc.tables:
                for table in doc.tables:
                    if len(table.rows) >= 6:
                        # 反思部分在第6行(索引5)
                        reflection_row = table.rows[5]
                        # 反思部分通常是合并单元格,所以取第一个单元格
                        if len(reflection_row.cells) >= 1:
                            reflection_cell = reflection_row.cells[0]
                            for paragraph in reflection_cell.paragraphs:
                                for run in paragraph.runs:
                                    # 设置为小四(12磅)
                                    run.font.size = Pt(12)
                                    # 确保是宋体
                                    run.font.name = '宋体'
                                    # 中文字体设置
                                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
                                    modified = True
            
            if modified:
                print(f"  ✅ 修复反思部分字体为小四宋体")
            
            # 生成文件名
            month_str = str(row['month']) if pd.notna(row['month']) and str(row['month']) != 'nan' else str(index+1)
            # try:
            #     month_formatted = f"{int(month_str):02d}月"
            # except:
            month_formatted = f"{month_str}月"
            
            topic_short = str(row['name0'])[:] if pd.notna(row['name0']) and str(row['name0']) != 'nan' else '四大教育'
            
            
            # filename = f"{month_formatted}_{kindgarden}_{original_classroom}_四大教育_{topic_short}_{CLASS_NAME[2]}()班.docx"
            # 客户要求样式大班XX教育(3月).docx
            filename = f"{topic_short}({month_formatted}).docx"
            file_full_path = os.path.join(OUTPUT_FOLDER, filename)
            
            # 保存修复后的文档
            doc.save(file_full_path)
            
            # 删除临时文件
            if os.path.exists(temp_path):
                os.remove(temp_path)
            
            generated_files.append(file_full_path)
            
            print(f"✅ 生成文档: {filename}")
            
        except Exception as e:
            print(f"❌ 生成第{index+1}行文档失败: {str(e)}")
            import traceback
            traceback.print_exc()
            continue
    
    print(f"\n📊 文档生成完成!共生成 {len(generated_files)} 个文档")
    print(f"📂 文档保存在: {OUTPUT_FOLDER}")
    return True

def process_word_document(input_path, output_path):
    """处理单个Word文档(aaa转手动换行符、空格缩进 + 修复字体大小)"""
    try:
        doc = Document(input_path)
        modified = False
        
        # 修复反思部分的字体大小(确保是小四)
        if doc.tables:
            for table in doc.tables:
                if len(table.rows) >= 6:
                    reflection_row = table.rows[5]
                    if len(reflection_row.cells) >= 1:
                        reflection_cell = reflection_row.cells[0]
                        for paragraph in reflection_cell.paragraphs:
                            for run in paragraph.runs:
                                # 设置为小四(12磅)
                                if run.font.size != Pt(12):
                                    run.font.size = Pt(12)
                                    run.font.name = '宋体'
                                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
                                    modified = True
        
        for table in doc.tables:
            for row_idx, row in enumerate(table.rows, 1):
                for col_idx, cell in enumerate(row.cells, 1):
                    # 收集所有需要处理的段落
                    paragraphs_to_process = []
                    for para_idx, para in enumerate(cell.paragraphs):
                        if 'aaa' in para.text:
                            paragraphs_to_process.append((para_idx, para))
                        # 添加空格缩进(第2列第7行)
                        if col_idx == 2 and row_idx == 7:
                            if para.text and not para.text.startswith(''):
                                para.text = '' + para.text
                                modified = True
                    
                    # 处理包含aaa的段落
                    for para_idx, para in paragraphs_to_process:
                        # 保存原格式
                        runs_info = []
                        for run in para.runs:
                            runs_info.append({
                                'text': run.text,
                                'bold': run.bold,
                                'italic': run.italic,
                                'underline': run.underline,
                                'font_name': run.font.name,
                                'font_size': run.font.size,
                                'color': run.font.color.rgb if run.font.color else None
                            })
                        
                        # 按aaa分割文本
                        full_text = para.text
                        parts = full_text.split('aaa')
                        
                        # 清除原段落
                        para.clear()
                        
                        # 重新添加分段内容
                        for i, part in enumerate(parts):
                            if part.strip():  # 如果有内容
                                # 创建新run并尝试保留原格式
                                run = para.add_run(part)
                                if runs_info:
                                    # 使用第一个run的格式(简化处理)
                                    run.bold = runs_info[0]['bold']
                                    run.italic = runs_info[0]['italic']
                                    run.underline = runs_info[0]['underline']
                                    if runs_info[0]['font_name']:
                                        run.font.name = runs_info[0]['font_name']
                                    if runs_info[0]['font_size']:
                                        run.font.size = runs_info[0]['font_size']
                                    if runs_info[0]['color']:
                                        run.font.color.rgb = runs_info[0]['color']
                            
                            # 如果不是最后一段,添加手动换行符
                            if i < len(parts) - 1:
                                para.add_run().add_break(WD_BREAK.LINE)
                        
                        modified = True
        
        # 保存文档
        doc.save(output_path)
        
        # 如果保存成功
        if os.path.exists(output_path):
            return True, modified
        else:
            return False, False
            
    except Exception as e:
        print(f"    错误: {str(e)}")
        import traceback
        traceback.print_exc()
        return False, False

def step3_process_documents():
    """第三步:处理生成的Word文档"""
    print("\n" + "="*60)
    print("第三步:处理Word文档(aaa转手动换行符、空格缩进)")
    print("="*60)
    
    # 创建输出文件夹
    os.makedirs(PROCESSED_FOLDER, exist_ok=True)
    
    print(f"输入文件夹: {OUTPUT_FOLDER}")
    print(f"输出文件夹: {PROCESSED_FOLDER}")
    print("-" * 60)
    
    # 检查输入文件夹
    if not os.path.exists(OUTPUT_FOLDER):
        print(f"❌ 错误: 输入文件夹不存在!")
        return False
    
    # 获取所有docx文件
    docx_files = [f for f in os.listdir(OUTPUT_FOLDER) 
                  if f.lower().endswith('.docx')]
    
    if not docx_files:
        print(f"⚠️ 没有找到docx文件!")
        return False
    
    print(f"\n✅ 找到 {len(docx_files)} 个docx文件")
    print("-" * 60)
    
    # 处理文件
    success = 0
    for i, filename in enumerate(docx_files, 1):
        print(f"[{i}/{len(docx_files)}] {filename}")
        
        input_path = os.path.join(OUTPUT_FOLDER, filename)
        output_filename = filename.replace('.docx', '.doc')
        output_path = os.path.join(PROCESSED_FOLDER, output_filename)
        
        result, modified = process_word_document(input_path, output_path)
        
        if result:
            if modified:
                print(f"  ✅ 已处理并保存")
            else:
                print(f"  ⚠️ 无修改内容,已复制")
            success += 1
        else:
            print(f"  ❌ 处理失败")
        
        print()
    
    print(f"\n✅ 处理完成!成功处理 {success}/{len(docx_files)} 个文件")
    print(f"📂 处理后文档保存在: {PROCESSED_FOLDER}")
    return True

def check_winrar_installed():
    """检查WinRAR是否安装"""
    possible_paths = [
        r"C:\Program Files\WinRAR\WinRAR.exe",
        r"C:\Program Files (x86)\WinRAR\WinRAR.exe"
    ]
    for path in possible_paths:
        if os.path.exists(path):
            return path
    return None

def step4_pack_to_rar():
    """第四步:打包成RAR文件"""
    print("\n" + "="*60)
    print("第四步:打包成RAR文件")
    print("="*60)
    
    # 检查最终文件夹是否存在
    if not os.path.exists(PROCESSED_FOLDER):
        print(f"❌ 错误:最终文件夹不存在 - {PROCESSED_FOLDER}")
        return False
    
    # 检查文件夹内是否有文件
    files = os.listdir(PROCESSED_FOLDER)
    if not files:
        print(f"⚠️ 警告:最终文件夹为空,没有文件可打包")
        return False
    
    print(f"📁 待打包文件夹: {PROCESSED_FOLDER}")
    print(f"📊 文件夹内共有 {len(files)} 个文件")
    
    # 方法1:尝试使用WinRAR(如果已安装)
    winrar_path = check_winrar_installed()
    if winrar_path:
        try:
            print("🔄 正在使用WinRAR打包...")
            # 构建WinRAR命令
            cmd = [
                winrar_path,
                'a',  # 添加到压缩文件
                '-ep1',  # 不保存路径信息
                '-r',  # 递归子目录
                RAR_PATH,
                f'{PROCESSED_FOLDER}\\*.*'
            ]
            
            # 执行命令
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if os.path.exists(RAR_PATH):
                size = os.path.getsize(RAR_PATH) / 1024  # KB
                print(f"✅ 打包成功!")
                print(f"📦 RAR文件: {RAR_PATH}")
                print(f"📏 文件大小: {size:.2f} KB")
                return True
            else:
                print("⚠️ WinRAR打包失败,尝试使用ZIP替代...")
                return create_zip_backup()
                
        except Exception as e:
            print(f"⚠️ WinRAR打包出错: {str(e)}")
            print("⚠️ 尝试使用ZIP替代...")
            return create_zip_backup()
    else:
        print("⚠️ 未找到WinRAR,将使用ZIP格式打包...")
        return create_zip_backup()

def create_zip_backup():
    """创建ZIP备份(当WinRAR不可用时)"""
    try:
        print("🔄 正在创建ZIP压缩文件...")
        
        # 创建ZIP文件
        with zipfile.ZipFile(ZIP_PATH, 'w', zipfile.ZIP_DEFLATED) as zipf:
            for root, dirs, files in os.walk(PROCESSED_FOLDER):
                for file in files:
                    file_path = os.path.join(root, file)
                    arcname = os.path.relpath(file_path, PROCESSED_FOLDER)
                    zipf.write(file_path, arcname)
        
        if os.path.exists(ZIP_PATH):
            size = os.path.getsize(ZIP_PATH) / 1024  # KB
            print(f"✅ ZIP打包成功!")
            print(f"📦 ZIP文件: {ZIP_PATH}")
            print(f"📏 文件大小: {size:.2f} KB")
            
            # 询问是否要重命名为RAR(虽然实际上是ZIP)
            print("\n注:由于系统没有安装WinRAR,已生成ZIP格式文件")
            print("如需RAR格式,请手动安装WinRAR后重新运行此步骤")
            
            return True
        else:
            print("❌ ZIP打包失败")
            return False
            
    except Exception as e:
        print(f"❌ ZIP打包出错: {str(e)}")
        return False

def main():
    """主函数 - 执行完整工作流"""
    print("\n" + "="*60)
    print("大班四大教育 - 完整工作流")
    print("="*60)
    print(f"基础路径: {BASE_PATH}")
    print(f"班级: {CLASS_NAME}")
    print(f"主题: {EDU_THEME}")
    print("="*60)
    
    # 自动执行完整工作流(不需要用户选择)
    print("\n开始执行完整工作流...")
    
    # # 第一步:生成Excel
    # if not step1_generate_excel():
    #     print("❌ 第一步失败,程序终止")
    #     return
    
    # 第二步:生成Word文档
    if not step2_generate_word_from_excel():
        print("❌ 第二步失败,程序终止")
        return
    
    # 第三步:处理文档
    if not step3_process_documents():
        print("❌ 第三步失败,程序终止")
        return
    
    # 第四步:打包成RAR
    step4_pack_to_rar()
    
    print("\n" + "="*60)
    print("🎉 完整工作流执行完成!")
    print("="*60)
    print(f"\n📂 生成的文件位置:")
    print(f"1. Excel占位符文件: {EXCEL_PATH}")
    print(f"2. 原始Word文档: {OUTPUT_FOLDER}")
    print(f"3. 处理后的Word文档: {PROCESSED_FOLDER}")
    
    # 显示打包文件
    if os.path.exists(RAR_PATH):
        print(f"4. RAR压缩包: {RAR_PATH}")
    elif os.path.exists(ZIP_PATH):
        print(f"4. ZIP压缩包: {ZIP_PATH}")
    
    print("="*60)

if __name__ == "__main__":
    main()

因为前期有一分园、二分园、中班的一系列模版和代码可以复用,所以这一份大班四大教育AI和批量生成都很快。大约30分钟

六、发送

相关推荐
陈童学哦1 小时前
FDE岗位年薪百万?拆解中小企业AI落地四步框架
人工智能
richard_first1 小时前
50.5% 美国人认为 AI 恋爱可能算出轨:AI 正在从“工具“变成“关系主体“
人工智能·microsoft
华清远见成都中心1 小时前
神经网络中的损失函数是什么
人工智能·深度学习·神经网络
小赵AI手记1 小时前
技术拆解(二十)具身智能:SO-ARM101抓取小狗的胡萝卜,我看见了AI如何降低跨行门槛
人工智能·机器人
AngusKit1 小时前
AngusTester 是什么:AI 原生软件测试
自动化测试·人工智能·测试工具·性能测试·web测试·api测试·llm测试
玖玥拾1 小时前
Lua 基础语法(六)xLua Lua 调用 C# 交互
开发语言·unity·c#·lua
知了一笑1 小时前
AI知识库,是捷径吗?
人工智能·ai·知识库
招风的黑耳1 小时前
【数据大屏】智慧城市节能减排类可视化大屏原型
人工智能·智慧城市