当前位置: 首页 > article >正文

【办公类-91-01】20250214“每周安排表”批量填写——数字“年月日”、文字“休息、节假日”

背景需求:

20250214作为信息员,我会每周去区里的“信息平台”上报“教育教学”相关的通讯。因此领导在周五把每周的周计划安排表(docx)发我。

因为之前做了校历、营养员的人数统计表、各班点名册、本班周计划教案。

【办公类-53-04】20250209Python模仿制作2024学年第二学期校历-CSDN博客文章浏览阅读432次,点赞14次,收藏5次。【办公类-53-04】20250209Python模仿制作2024学年第二学期校历 https://blog.csdn.net/reasonsummer/article/details/145537780?sharetype=blogdetail&sharerId=145537780&sharerefer=PC&sharesource=reasonsummer&spm=1011.2480.3001.8118【办公类-54-03】20250219营养员《每周人数统计表》(双休日、国定假日,变成灰色)-CSDN博客文章浏览阅读933次,点赞21次,收藏17次。【办公类-54-03】20250219营养员《每周人数统计表》(双休国定假涂成灰色) https://blog.csdn.net/reasonsummer/article/details/145577907?spm=1001.2014.3001.5501【办公类-54-04】20250210班级点名册模版(双休国定假涂成灰色)2024学年第二学期,读取上学期名单-CSDN博客文章浏览阅读848次,点赞32次,收藏9次。【办公类-54-04】20250210班级点名册模版(双休国定假涂成灰色)2024学年第二学期,读取上学期名单 https://blog.csdn.net/reasonsummer/article/details/145583809?spm=1001.2014.3001.5501

所以,我立刻从这份周安排里看到了“周次、起止月日、周一到周五、五天年月”

运用营养员的7天思路,把每周安排里的日期都批量做好吧

WORD模版

把第一周的模版分析需要哪些数据:

1、标题栏:周次、一周的周一(年月)、一周的周五(年月)

2、侧边栏:一周的每天的日期(月、日)、星期(周一到周五)

我觉得还是统一做一周7天的模版(如4月27日周日调休上班),同时双休日也有部分老师或领导也要干活(参加工会活动或者带孩子们参加OM比赛等)

所以模版统一做成7天,星期一到日的汉字直接写模版里,标题日期统一写周一到周日的日期(年月日)

对应的EXCLE标题制作

'''
把领导的每周安排的模版的日期批量做好(1)——制作日期数字
如果有空格,全部要加一个空格,否则读取出来的年月日是一位小数浮点数
星火讯飞,阿夏
2025年2月14日
'''


# -*- coding: utf-8 -*-

import datetime
import openpyxl
from openpyxl.styles import Alignment, PatternFill
import time

import pandas as pd
import re
from openpyxl import load_workbook

# for 

path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250214领导的每周安排模板'

# 1、制作基础日期表

title='2024学年第二学期校历'

tt=path+fr"\02-01 {title}.xlsx"

# 创建一个新的Excel工作簿
workbook = openpyxl.Workbook()
sheet = workbook.active

# 设置标题行
title_row = ["week", "D1", "D2", "D3", "D4", "D5", "D6", "D7"]
sheet.append(title_row)

# 设置日期范围
start_date = datetime.date(2025, 2, 17)
end_date = datetime.date(2025, 6, 30)

# 计算周数和日期
current_week = 1
current_day = start_date
while current_day <= end_date:
    # 获取当前周的第一天(星期一)
    week_start = current_day - datetime.timedelta(days=current_day.weekday())
    
    # 如果当前日期是新的一周,添加新行并更新周数
    if current_day == week_start:
        sheet.append([f"第{current_week:02d}周"])
        current_week += 1
    
    # 在正确的单元格中添加日期
    column_index = current_day.weekday() + 2  # 从B列开始,所以加2year
    cell = sheet.cell(row=current_week, column=column_index)
    
    # 不同的表示方法
    # cell.value = current_day.strftime("%Y-%m-%d")    # 2024-09-01    
    # cell.value = current_day.strftime("%Y-%#m-%#d")    # 2024-9-1
    # cell.value = current_day.strftime("%m/%d")      # 09-01
    # cell.value = current_day.strftime("%#m/%#d")    # 9-1
    # cell.value = current_day.strftime('%Y{y}%m{m}%d{d}').format(y='年', m='月', d='日')   # 2024年09月01日
    cell.value = current_day.strftime('%Y{y}%#m{m}%#d{d}').format(y='年', m='月', d='日')  # 2024年9月1日
    
    
    
    cell.alignment = Alignment(horizontal='center', vertical='center')
    
     # 如果日期不等于周六和周日,就把这个单元格填充为浅黄色
    if current_day.weekday() not in (5, 6):
        light_yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
        cell.fill = light_yellow_fill

    
    
    # 如果日期等于2024-09-14、2024-10-12、9月16日、9月17日、10月1日到10月8日、2025年1月1日,单元格填充为白色
    special_dates = [datetime.date(2025, 4, 4), datetime.date(2025, 5, 1), datetime.date(2025, 5, 2), datetime.date(2025, 5, 5),datetime.date(2025, 6, 2)]
    # for i in range(1, 8):
    #     special_dates.append(datetime.date(2024, 10, i))
    # special_dates.append(datetime.date(2025, 1, 1))
    if current_day in special_dates:
        white_fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
        cell.fill = white_fill

    # # 如果日期等于2024-09-14或2024-10-12,单元格填充为黄色
    # if current_day == datetime.date(2025, 4, 27) or current_day == datetime.date(2024, 9, 29) or current_day == datetime.date(2024, 10, 12):
    if current_day == datetime.date(2025, 4, 27):
        yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
        cell.fill = yellow_fill
    
    # 移动到下一天
    current_day += datetime.timedelta(days=1)
   

# 设置列宽
for col in range(1, 30):
    sheet.column_dimensions[openpyxl.utils.get_column_letter(col)].width = 15
# for col in range(9, 12):
#     sheet.column_dimensions[openpyxl.utils.get_column_letter(col)].width = 35
# 设置单元格文字居中
for row in sheet.iter_rows():
    for cell in row:
        cell.alignment = openpyxl.styles.Alignment(horizontal='center', vertical='center')

# 打印所有黄色底纹填充格子的坐标
yellow_coordinates = []
for row in sheet.iter_rows():
    for cell in row:
        if cell.fill and cell.fill.start_color.rgb == 'FFFF00':
            yellow_coordinates.append((cell.row, cell.column))

print("Yellow filled cells coordinates:", yellow_coordinates)

# 以下是拆分信息(提取第一天和最后一天)
    # 
# workbook.save(tt)
# time.sleep(1)
# # 读取第3列第二行开始的单元格文字,截取“年”前面的部分,写入第12列的第2行写入。同时在第12列的第1行写入“year”
# # 示例数据
# # b = [3, 4,5]


    

# # 加载已存在的Excel文件
# workbook = openpyxl.load_workbook(tt)
# sheet = workbook.active
n=1
# 读取标题中的信息
# 读取B列:
for i in range(2, sheet.max_row + 1):        
    cell_value = sheet.cell(row=i, column=2).value
    # for x in range(9,12):
    if cell_value:
        match = re.search(r'(\d+)年', cell_value)
        year_part = match.group(1)
        sheet.cell(row=i, column=9).value = year_part
    if cell_value:
        match = re.search(r'年(\d+)月', cell_value)
        month_part = match.group(1)
        sheet.cell(row=i, column=10).value = month_part
    if cell_value:
        match = re.search(r'月(\d+)日', cell_value)
        day_part = match.group(1)
        sheet.cell(row=i, column=11).value = day_part

    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=9).value = f"year1"
    sheet.cell(row=1, column=10).value = f"month1"
    sheet.cell(row=1, column=11).value = f"day11"

# 读取H列:
for i in range(2, sheet.max_row + 1):        
    cell_value = sheet.cell(row=i, column=8).value
    # for x in range(9,12):
    if cell_value:
        match = re.search(r'(\d+)年', cell_value)
        year_part = match.group(1)
        sheet.cell(row=i, column=12).value = year_part
    if cell_value:
        match = re.search(r'年(\d+)月', cell_value)
        month_part = match.group(1)
        sheet.cell(row=i, column=13).value = month_part
    if cell_value:
        match = re.search(r'月(\d+)日', cell_value)
        day_part = match.group(1)
        sheet.cell(row=i, column=14).value =f'{day_part}'

    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=12).value = f"year2"
    sheet.cell(row=1, column=13).value = f"month2"
    sheet.cell(row=1, column=14).value = f"day22"


# 读取玥日
# 读取各列中的日期,提取月和日,写入相应列
columns_to_process = [2, 3, 4, 5, 6,7,8]  # B列到F列
output_columns = [15, 16, 17, 18, 19,20,21]  # 对应输出的列(H列到L列)

for col_idx, col in enumerate(columns_to_process):
    for i in range(2, sheet.max_row + 1):        
        cell_value = sheet.cell(row=i, column=col).value
        if cell_value:
            match = re.search(r'(\d+)年(\d+)月(\d+)日', cell_value)
            if match:
                month_part = match.group(2)
                day_part = match.group(3)
                sheet.cell(row=i, column=output_columns[col_idx]).value = f"{month_part}.{day_part}"
    
    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=output_columns[col_idx]).value = f"day{col_idx+1}"

# # 读取各列中的日期,提取月和日,写入相应列

# 设置黄色填充样式
yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")



# 要处理的列和对应的输出列
columns_to_process = [2, 3, 4, 5, 6, 7,8]  # B列到G列
output_columns = [22, 23, 24, 25, 26, 27,28]  # 对应输出的列(Y列到D列)

for col_idx, col in enumerate(columns_to_process):
    for i in range(2, sheet.max_row + 1):        
        cell = sheet.cell(row=i, column=col)
        cell_value = cell.value
        
        # 如果单元格有黄色填充,则复制填充样式到输出列
        if cell.fill == yellow_fill:
            output_cell = sheet.cell(row=i, column=output_columns[col_idx])
            output_cell.fill = yellow_fill

        else:
         # 如果单元格没有黄色填充(白色),就在里面写入“双休日休息”
            sheet.cell(row=i, column=output_columns[col_idx]).value = "休息"

        # else:
        # 只对真正放假的那一天进行备注 清明1天,劳动1天
        dayss=['2025年4月4日','2025年4月27日','2025年5月1日','2025年5月31日',]
        jr=['清明节放假','劳动节调班,今天要上班的!','劳动节放假','端午节放假']

        for ddd in range(len(dayss)):
        # 检查日期是否为2025年4月4日
            if  cell_value ==dayss[ddd]:
                sheet.cell(row=i, column=output_columns[col_idx]).value = jr[ddd]
    
    # 在第12列的第1行写入“year”,复制的时候不要复制文字
    sheet.cell(row=1, column=output_columns[col_idx]).value = f"x{col_idx+1}"

# 保存工作簿
workbook.save(tt)

这个代码运行后,直接出现一个EXCEL

代码的第1部分生成基本的起止日期(20周)并用黄色标出上班的日期

代码第2部分提取B列(列名:D1)(每周第一天周一)的年、月、日,分别放在I、J、K列

代码第2部分提取H列(列名:D7)(每周第七天周日)的年、月、日,分别放在LMN列

代码第3部分是,把D1-D7的年月日里,提取其中的“月”+“日”,变成文件名上的日期,写入day1-day7

代码第4部分是,把D1-D7的年月日,如果格子里黄色底纹,就复制到x1-x7里(只复制底纹,不复制文字)、没有黄色底纹的地方(白色)就全部写入“休息”(包括双休日和节假日的空格),最后查找特殊节日的年月日,如果有这些日期的格子,再对应的格子写入“XX节放假”

我是根据网络日历写的,它们显示,真正的“XX节”实际只有1天,放的3天、5天,大部分是双休日,所以我写了一天“XX节”。其他几天都是“休息”,并不是3、5天都写XX节

现在EXCLE生成的表格做好了。

我后面后面代码生成批量docx后,发现文件名的第二个日期变成了1位浮点数,但是第一个日期是正常的

内部的标题里面的第二个日期(年月日)也变成了1位浮点数。

研究半天,是因为6月30日后面的日期是空的。如果输入一个空格,它就能够显示出来

所以第一个代码的最后一步就是读取行数,然后查找I-U列里面是否有空格,有空格就输入一个“ ”

现在是什么都没有。

添加一段代码,先把空单元格写入111

顺利替换为111

生成的EXCLE里面,空单元格里面就有一个‘ ’看不见的空格

用第二个代码运行后,第二个日期也正常了

第一个修改代码

'''
把领导的每周安排的模版的日期批量做好(2)——批量生成模版
如果有空格,全部要加一个空格,否则读取出来的年月日是一位小数浮点数
星火讯飞,阿夏
2025年2月14日
'''


import pandas as pd
import openpyxl
from openpyxl import load_workbook
import copy


print('------------1、读取表格里整理好的周日、日期,列表形式')

# 一、导入相关模块,设定excel所在文件夹和生成word保存的文件夹
from docxtpl import DocxTemplate
import pandas as pd
import os

print('----1、第一次新WORD制作--------')
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250214领导的每周安排模板'
print(path)

file_path=path
print(file_path)
os.makedirs(file_path,exist_ok=True)


print('----计算每一行的数据用5天、6天还是7天的表格------')

import xlrd  
  
# 假设 path 是之前已经定义好的文件路径变量的一部分  
file_paths = path + r'\02-01 2024学年第二学期校历.xlsx'  
workbook = xlrd.open_workbook(file_paths)  
sheet = workbook.sheet_by_index(0)  # 获取第一张工作表    
new=path+r'\00每周安排模板1-20周(有日期)'
os.makedirs(new,exist_ok=True)

# 遍历每一行,从第二行开始(索引为1,因为索引从0开始,但Excel从1开始计数行)  
for row_idx in range(1,sheet.nrows):  # sheet.nrows 返回工作表中的行数  
    # 读取当前行的E到K列(列索引从0开始,但Excel列从1开始计数,所以E=4, ..., K=10)  
    row_data = sheet.row_values(row_idx, start_colx=4, end_colx=11)  
    # print(row_data)
    
    # 删除 row_data 中的空元素(None 或空字符串)  
    days = [cell for cell in row_data if cell is not None and cell != '']  
      
    # 统计每行非空元素的数量  (天数)
    day = len(days)  
    print(f'第{row_idx}行,本周天数是{day}天')

    

    # 如果是5天就用5天模版,如果是7天,就用7天模版

    tpl = DocxTemplate(path+fr'\00 周计划模板 年月日.docx')

    WeeklyPlan = pd.read_excel(path+r'\02-01 2024学年第二学期校历.xlsx')
  
   
    week =WeeklyPlan["week"].str.rstrip() 

    year1 = WeeklyPlan["year1"].astype(str).str.rstrip() 
    year2 = WeeklyPlan["year2"].astype(str).str.rstrip() 
    month1 = WeeklyPlan["month1"].astype(str).str.rstrip() 
    month2 = WeeklyPlan["month2"].astype(str).str.rstrip() 
    day11 = WeeklyPlan["day11"].astype(str).str.rstrip() 
    day22 = WeeklyPlan["day22"].astype(str).str.rstrip() 
    

    day1 = WeeklyPlan["day1"].astype(str).str.rstrip() 
    # print(day1)
    day2 = WeeklyPlan["day2"].astype(str).str.rstrip() 
    day3 = WeeklyPlan["day3"].astype(str).str.rstrip() 
    day4 = WeeklyPlan["day4"].astype(str).str.rstrip() 
    day5 = WeeklyPlan["day5"].astype(str).str.rstrip() 
    day6 = WeeklyPlan["day6"].astype(str).str.rstrip() 
    day7 = WeeklyPlan["day7"].astype(str).str.rstrip() 

    
    x1 = WeeklyPlan["x1"].str.rstrip() 
    x2 = WeeklyPlan["x2"].str.rstrip()
    x3 = WeeklyPlan["x3"].str.rstrip() 
    x4 = WeeklyPlan["x4"].str.rstrip()
    x5 = WeeklyPlan["x5"].str.rstrip() 
    x6 = WeeklyPlan["x6"].str.rstrip()
    x7 = WeeklyPlan["x7"].str.rstrip() 

   
    # 遍历excel行,逐个生成
    # num = WeeklyPlan.shape[0]
    # print(num)
    for i in range(row_idx-1,row_idx):
        context = {
      

            "week": int(week[i][1:-1]),
            # 只要第01周里面的1
            "year1": year1[i],
            "year2": year2[i],
            "month1": month1[i],
            "month2": month2[i],
            "day11": day11[i],
            "day22": day22[i],
            
            "day1": day1[i],
            "day2": day2[i],
            "day3": day3[i], 
            "day4": day4[i],
            "day5": day5[i],
            "day6": day6[i],
            "day7": day7[i],          
          

            "x1": x1[i],
            "x2": x2[i],
            "x3": x3[i],
            "x4": x4[i],
            "x5": x5[i],
            "x6": x6[i],
            "x7": x7[i],
           
            }        
        tpl.render(context)  
    #         # 假设 weekshu[i] 是类似于 '4、5' 或 '7' 这样的字符串

        # if isinstance(week[i], str) and len(week[i]) >= 3:  
            # week_part1 = str(week[i]).split('、')[0]  # 分割字符串并取第一部分
            # week_number1 = int(week_part)  # 转换为整数
            # week_number2=week_number1+1  
            # formatted_week_number = '%02d' % week_number1+'_'+'%02d' % week_number2 
            # tpl.save(file_path+fr"\ 第{str(week[i][1:-1])}周 每周安排.docx")
            # .docx")
    

        if (day7[i]) =='':
            day1[i]
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~).docx")

        else:
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~{month2[i]}.{day22[i]}).docx")


        # else:
        #     tpl.save(file_path+fr"\{weekshu[i]:02} 第{str(week[i][1:-1])}周 每周安排 ({day1[i]}+'~'+{day7[i]}).docx")

# 把nan(空值)删除
import os
from docx import Document

folder_path = new
# y=['A','nan']
# z=['.','']
# for s in range(len(y)):
for filename in os.listdir(folder_path):
    if filename.endswith('.docx'):
        file_path = os.path.join(folder_path, filename)
        doc = Document(file_path)
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    if cell.text == 'nan':
                        cell.text = ''
                        
        doc.save(file_path)
        print(f"Processed {filename}")



第二步就是根据模版,一一对应写入了

直接上代码

'''
把领导的每周安排的模版的日期批量做好(2)——批量生成模版
如果有空格,全部要加一个空格,否则读取出来的年月日是一位小数浮点数
星火讯飞,阿夏
2025年2月14日
'''


import pandas as pd
import openpyxl
from openpyxl import load_workbook
import copy


print('------------1、读取表格里整理好的周日、日期,列表形式')

# 一、导入相关模块,设定excel所在文件夹和生成word保存的文件夹
from docxtpl import DocxTemplate
import pandas as pd
import os

print('----1、第一次新WORD制作--------')
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250214领导的每周安排模板'
print(path)

file_path=path
print(file_path)
os.makedirs(file_path,exist_ok=True)


print('----计算每一行的数据用5天、6天还是7天的表格------')

import xlrd  
  
# 假设 path 是之前已经定义好的文件路径变量的一部分  
file_paths = path + r'\02-01 2024学年第二学期校历.xlsx'  
workbook = xlrd.open_workbook(file_paths)  
sheet = workbook.sheet_by_index(0)  # 获取第一张工作表    
new=path+r'\00每周安排模板1-20周(有日期)'
os.makedirs(new,exist_ok=True)

# 遍历每一行,从第二行开始(索引为1,因为索引从0开始,但Excel从1开始计数行)  
for row_idx in range(1,sheet.nrows):  # sheet.nrows 返回工作表中的行数  
    # 读取当前行的E到K列(列索引从0开始,但Excel列从1开始计数,所以E=4, ..., K=10)  
    row_data = sheet.row_values(row_idx, start_colx=4, end_colx=11)  
    # print(row_data)
    
    # 删除 row_data 中的空元素(None 或空字符串)  
    days = [cell for cell in row_data if cell is not None and cell != '']  
      
    # 统计每行非空元素的数量  (天数)
    day = len(days)  
    print(f'第{row_idx}行,本周天数是{day}天')

    

    # 如果是5天就用5天模版,如果是7天,就用7天模版

    tpl = DocxTemplate(path+fr'\00 周计划模板 年月日.docx')

    WeeklyPlan = pd.read_excel(path+r'\02-01 2024学年第二学期校历.xlsx')
  
   
    week =WeeklyPlan["week"].str.rstrip() 

    year1 = WeeklyPlan["year1"].astype(str).str.rstrip() 
    year2 = WeeklyPlan["year2"].astype(str).str.rstrip() 
    month1 = WeeklyPlan["month1"].astype(str).str.rstrip() 
    month2 = WeeklyPlan["month2"].astype(str).str.rstrip() 
    day11 = WeeklyPlan["day11"].astype(str).str.rstrip() 
    day22 = WeeklyPlan["day22"].astype(str).str.rstrip() 
    

    day1 = WeeklyPlan["day1"].astype(str).str.rstrip() 
    # print(day1)
    day2 = WeeklyPlan["day2"].astype(str).str.rstrip() 
    day3 = WeeklyPlan["day3"].astype(str).str.rstrip() 
    day4 = WeeklyPlan["day4"].astype(str).str.rstrip() 
    day5 = WeeklyPlan["day5"].astype(str).str.rstrip() 
    day6 = WeeklyPlan["day6"].astype(str).str.rstrip() 
    day7 = WeeklyPlan["day7"].astype(str).str.rstrip() 

    
    x1 = WeeklyPlan["x1"].str.rstrip() 
    x2 = WeeklyPlan["x2"].str.rstrip()
    x3 = WeeklyPlan["x3"].str.rstrip() 
    x4 = WeeklyPlan["x4"].str.rstrip()
    x5 = WeeklyPlan["x5"].str.rstrip() 
    x6 = WeeklyPlan["x6"].str.rstrip()
    x7 = WeeklyPlan["x7"].str.rstrip() 

   
    # 遍历excel行,逐个生成
    # num = WeeklyPlan.shape[0]
    # print(num)
    for i in range(row_idx-1,row_idx):
        context = {
      

            "week": int(week[i][1:-1]),
            # 只要第01周里面的1
            "year1": year1[i],
            "year2": year2[i],
            "month1": month1[i],
            "month2": month2[i],
            "day11": day11[i],
            "day22": day22[i],
            
            "day1": day1[i],
            "day2": day2[i],
            "day3": day3[i], 
            "day4": day4[i],
            "day5": day5[i],
            "day6": day6[i],
            "day7": day7[i],          
          

            "x1": x1[i],
            "x2": x2[i],
            "x3": x3[i],
            "x4": x4[i],
            "x5": x5[i],
            "x6": x6[i],
            "x7": x7[i],
           
            }        
        tpl.render(context)  
    #         # 假设 weekshu[i] 是类似于 '4、5' 或 '7' 这样的字符串

        # if isinstance(week[i], str) and len(week[i]) >= 3:  
            # week_part1 = str(week[i]).split('、')[0]  # 分割字符串并取第一部分
            # week_number1 = int(week_part)  # 转换为整数
            # week_number2=week_number1+1  
            # formatted_week_number = '%02d' % week_number1+'_'+'%02d' % week_number2 
            # tpl.save(file_path+fr"\ 第{str(week[i][1:-1])}周 每周安排.docx")
            # .docx")
    

        if (day7[i]) =='':
            day1[i]
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~).docx")

        else:
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~{month2[i]}.{day22[i]}).docx")


        # else:
        #     tpl.save(file_path+fr"\{weekshu[i]:02} 第{str(week[i][1:-1])}周 每周安排 ({day1[i]}+'~'+{day7[i]}).docx")

# 把nan(空值)删除
import os
from docx import Document

folder_path = new
# y=['A','nan']
# z=['.','']
# for s in range(len(y)):
for filename in os.listdir(folder_path):
    if filename.endswith('.docx'):
        file_path = os.path.join(folder_path, filename)
        doc = Document(file_path)
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    if cell.text == 'nan':
                        cell.text = ''
                        
        doc.save(file_path)
        print(f"Processed {filename}")



结果展示

内部标题的第二个日期也正常了,说明不能有“空单元格”

发给领导们用于制作每周安排。

与领导1的沟通 记录,调整样式,添加统一的文字模版

与领导2的沟通记录

此处发现第二个日期的问题,(3.10、6.30的日期会自动变成3.1、6.3)

当时我发现6.10(6月30人)读出来总是6.1(把它当做浮点,而不是日期)所以我用了.2f,结果6.7(6月7日)也变成6.70。

放弃用两位数。最终通过相对复杂的方式让10日、20日、30日这种,容易被认为是浮点数而舍弃0的月日格式,能够保留2个数字。

这是最终的版本了。

第1代码

'''
把领导的每周安排的模版的日期批量做好(1)——制作日期数字
如果有空格,全部要加一个空格,否则读取出来的年月日是一位小数浮点数
星火讯飞,阿夏
2025年2月14日
'''


# -*- coding: utf-8 -*-

import datetime
import openpyxl
from openpyxl.styles import Alignment, PatternFill
import time

import pandas as pd
import re
from openpyxl import load_workbook

# for 

path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250214领导的每周安排模板'

# 1、制作基础日期表

title='2024学年第二学期校历'

tt=path+fr"\02-01 {title}.xlsx"

# 创建一个新的Excel工作簿
workbook = openpyxl.Workbook()
sheet = workbook.active

# 设置标题行
title_row = ["week", "D1", "D2", "D3", "D4", "D5", "D6", "D7"]
sheet.append(title_row)

# 设置日期范围
start_date = datetime.date(2025, 2, 17)
end_date = datetime.date(2025, 6, 30)

# 计算周数和日期
current_week = 1
current_day = start_date
while current_day <= end_date:
    # 获取当前周的第一天(星期一)
    week_start = current_day - datetime.timedelta(days=current_day.weekday())
    
    # 如果当前日期是新的一周,添加新行并更新周数
    if current_day == week_start:
        sheet.append([f"第{current_week:02d}周"])
        current_week += 1
    
    # 在正确的单元格中添加日期
    column_index = current_day.weekday() + 2  # 从B列开始,所以加2year
    cell = sheet.cell(row=current_week, column=column_index)
    
    # 不同的表示方法
    # cell.value = current_day.strftime("%Y-%m-%d")    # 2024-09-01    
    # cell.value = current_day.strftime("%Y-%#m-%#d")    # 2024-9-1
    # cell.value = current_day.strftime("%m/%d")      # 09-01
    # cell.value = current_day.strftime("%#m/%#d")    # 9-1
    # cell.value = current_day.strftime('%Y{y}%m{m}%d{d}').format(y='年', m='月', d='日')   # 2024年09月01日
    cell.value = current_day.strftime('%Y{y}%#m{m}%#d{d}').format(y='年', m='月', d='日')  # 2024年9月1日
    
    
    
    cell.alignment = Alignment(horizontal='center', vertical='center')
    
     # 如果日期不等于周六和周日,就把这个单元格填充为浅黄色
    if current_day.weekday() not in (5, 6):
        light_yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
        cell.fill = light_yellow_fill

    
    
    # 如果日期等于2024-09-14、2024-10-12、9月16日、9月17日、10月1日到10月8日、2025年1月1日,单元格填充为白色
    special_dates = [datetime.date(2025, 4, 4), datetime.date(2025, 5, 1), datetime.date(2025, 5, 2), datetime.date(2025, 5, 5),datetime.date(2025, 6, 2)]
    # for i in range(1, 8):
    #     special_dates.append(datetime.date(2024, 10, i))
    # special_dates.append(datetime.date(2025, 1, 1))
    if current_day in special_dates:
        white_fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
        cell.fill = white_fill

    # # 如果日期等于2024-09-14或2024-10-12,单元格填充为黄色
    # if current_day == datetime.date(2025, 4, 27) or current_day == datetime.date(2024, 9, 29) or current_day == datetime.date(2024, 10, 12):
    if current_day == datetime.date(2025, 4, 27):
        yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
        cell.fill = yellow_fill
    
    # 移动到下一天
    current_day += datetime.timedelta(days=1)

# 在年月日起止和4.30样式的7天里,如果遇到什么都没有填写的空单元格,就写入一个空格   
# 读取最大行数(不要第一行)
max_row = sheet.max_row



# 设置列宽
for col in range(1, 30):
    sheet.column_dimensions[openpyxl.utils.get_column_letter(col)].width = 15
# for col in range(9, 12):
#     sheet.column_dimensions[openpyxl.utils.get_column_letter(col)].width = 35
# 设置单元格文字居中
for row in sheet.iter_rows():
    for cell in row:
        cell.alignment = openpyxl.styles.Alignment(horizontal='center', vertical='center')

# 打印所有黄色底纹填充格子的坐标
yellow_coordinates = []
for row in sheet.iter_rows():
    for cell in row:
        if cell.fill and cell.fill.start_color.rgb == 'FFFF00':
            yellow_coordinates.append((cell.row, cell.column))

print("Yellow filled cells coordinates:", yellow_coordinates)


n=1
# 读取标题中的信息
# 读取B列:
for i in range(2, sheet.max_row + 1):        
    cell_value = sheet.cell(row=i, column=2).value
    # for x in range(9,12):
    if cell_value:
        match = re.search(r'(\d+)年', cell_value)
        year_part = match.group(1)
        sheet.cell(row=i, column=9).value = year_part
    if cell_value:
        match = re.search(r'年(\d+)月', cell_value)
        month_part = match.group(1)
        sheet.cell(row=i, column=10).value = month_part
    if cell_value:
        match = re.search(r'月(\d+)日', cell_value)
        day_part = match.group(1)
        sheet.cell(row=i, column=11).value = day_part

    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=9).value = f"year1"
    sheet.cell(row=1, column=10).value = f"month1"
    sheet.cell(row=1, column=11).value = f"day11"

# 读取H列:
for i in range(2, sheet.max_row + 1):        
    cell_value = sheet.cell(row=i, column=8).value
    # for x in range(9,12):
    if cell_value:
        match = re.search(r'(\d+)年', cell_value)
        year_part = match.group(1)
        sheet.cell(row=i, column=12).value = year_part
    if cell_value:
        match = re.search(r'年(\d+)月', cell_value)
        month_part = match.group(1)
        sheet.cell(row=i, column=13).value = month_part
    if cell_value:
        match = re.search(r'月(\d+)日', cell_value)
        day_part = match.group(1)
        sheet.cell(row=i, column=14).value =f'{day_part}'

    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=12).value = f"year2"
    sheet.cell(row=1, column=13).value = f"month2"
    sheet.cell(row=1, column=14).value = f"day22"


# 读取玥日
# 读取各列中的日期,提取月和日,写入相应列
columns_to_process = [2, 3, 4, 5, 6,7,8]  # B列到F列
output_columns = [15, 16, 17, 18, 19,20,21]  # 对应输出的列(H列到L列)

for col_idx, col in enumerate(columns_to_process):
    for i in range(2, sheet.max_row + 1):        
        cell_value = sheet.cell(row=i, column=col).value
        if cell_value:
            match = re.search(r'(\d+)年(\d+)月(\d+)日', cell_value)
            if match:
                month_part = match.group(2)
                day_part = match.group(3)
                sheet.cell(row=i, column=output_columns[col_idx]).value = f"{month_part}.{day_part}"
    
    # 在第12列的第1行写入“year”    
    sheet.cell(row=1, column=output_columns[col_idx]).value = f"day{col_idx+1}"

# 检查第9到21列的范围内单元格,如果内容是空的,就在这个单元格里写入一个“ ”
columns_to_check = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
for i in range(2, max_row + 1):
    for col in columns_to_check:
        cell_value = sheet.cell(row=i, column=col).value
        if cell_value is None or cell_value == '':
            sheet.cell(row=i, column=col).value = ' '

# # 读取各列中的日期,提取月和日,写入相应列

# 设置黄色填充样式
yellow_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")


# 要处理的列和对应的输出列
columns_to_process = [2, 3, 4, 5, 6, 7,8]  # B列到G列
output_columns = [22, 23, 24, 25, 26, 27,28]  # 对应输出的列(Y列到D列)

for col_idx, col in enumerate(columns_to_process):
    for i in range(2, sheet.max_row + 1):        
        cell = sheet.cell(row=i, column=col)
        cell_value = cell.value
        
        # 如果单元格有黄色填充,则复制填充样式到输出列
        if cell.fill == yellow_fill:
            output_cell = sheet.cell(row=i, column=output_columns[col_idx])
            output_cell.fill = yellow_fill

        else:
         # 如果单元格没有黄色填充(白色),就在里面写入“双休日休息”
            sheet.cell(row=i, column=output_columns[col_idx]).value = "休息"

        # else:
        # 只对真正放假的那一天进行备注 清明1天,劳动1天
        dayss=['2025年4月4日','2025年4月27日','2025年5月1日','2025年5月31日',]
        jr=['清明节放假','劳动节调班,今天要上班的!','劳动节放假','端午节放假']

        for ddd in range(len(dayss)):
        # 检查日期是否为2025年4月4日
            if  cell_value ==dayss[ddd]:
                sheet.cell(row=i, column=output_columns[col_idx]).value = jr[ddd]
    
    # 在第12列的第1行写入“year”,复制的时候不要复制文字
    sheet.cell(row=1, column=output_columns[col_idx]).value = f"x{col_idx+1}"



# 保存工作簿
workbook.save(tt)

第2代码-批量DOCX

'''
把领导的每周安排的模版的日期批量做好(2)——批量生成模版
如果有空格,全部要加一个空格,否则读取出来的年月日是一位小数浮点数
星火讯飞,阿夏
2025年2月14日
'''


import pandas as pd
import openpyxl
from openpyxl import load_workbook
import copy


print('------------1、读取表格里整理好的周日、日期,列表形式')

# 一、导入相关模块,设定excel所在文件夹和生成word保存的文件夹
from docxtpl import DocxTemplate
import pandas as pd
import os

print('----1、第一次新WORD制作--------')
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250214领导的每周安排模板'
print(path)

file_path=path
print(file_path)
os.makedirs(file_path,exist_ok=True)


print('----计算每一行的数据用5天、6天还是7天的表格------')

import xlrd  
  
# 假设 path 是之前已经定义好的文件路径变量的一部分  
file_paths = path + r'\02-01 2024学年第二学期校历.xlsx'  
workbook = xlrd.open_workbook(file_paths)  
sheet = workbook.sheet_by_index(0)  # 获取第一张工作表    
new=path+r'\00每周安排模板1-20周(有日期)'
os.makedirs(new,exist_ok=True)



# 遍历每一行,从第二行开始(索引为1,因为索引从0开始,但Excel从1开始计数行)  
for row_idx in range(1,sheet.nrows):  # sheet.nrows 返回工作表中的行数  
    # 读取当前行的E到K列(列索引从0开始,但Excel列从1开始计数,所以E=4, ..., K=10)  
    row_data = sheet.row_values(row_idx, start_colx=4, end_colx=11)  
    # print(row_data)
    
    # 删除 row_data 中的空元素(None 或空字符串)  
    days = [cell for cell in row_data if cell is not None and cell != '']  
      
    # 统计每行非空元素的数量  (天数)
    day = len(days)  
    print(f'第{row_idx}行,本周天数是{day}天')

    

    # 如果是5天就用5天模版,如果是7天,就用7天模版

    tpl = DocxTemplate(path+fr'\00 周计划模板 年月日.docx')

    WeeklyPlan = pd.read_excel(path+r'\02-01 2024学年第二学期校历.xlsx')
  
   
    week =WeeklyPlan["week"].str.rstrip() 

    year1 = WeeklyPlan["year1"].astype(str).str.rstrip() 
    year2 = WeeklyPlan["year2"].astype(str).str.rstrip() 
    month1 = WeeklyPlan["month1"].astype(str).str.rstrip() 
    month2 = WeeklyPlan["month2"].astype(str).str.rstrip() 
    day11 = WeeklyPlan["day11"].astype(str).str.rstrip() 
    day22 = WeeklyPlan["day22"].astype(str).str.rstrip() 
    

    day1 = WeeklyPlan["day1"].astype(str).str.rstrip() 
    # print(day1)
    day2 = WeeklyPlan["day2"].astype(str).str.rstrip() 
    day3 = WeeklyPlan["day3"].astype(str).str.rstrip() 
    day4 = WeeklyPlan["day4"].astype(str).str.rstrip() 
    day5 = WeeklyPlan["day5"].astype(str).str.rstrip() 
    day6 = WeeklyPlan["day6"].astype(str).str.rstrip() 
    day7 = WeeklyPlan["day7"].astype(str).str.rstrip() 

    
    x1 = WeeklyPlan["x1"].str.rstrip() 
    x2 = WeeklyPlan["x2"].str.rstrip()
    x3 = WeeklyPlan["x3"].str.rstrip() 
    x4 = WeeklyPlan["x4"].str.rstrip()
    x5 = WeeklyPlan["x5"].str.rstrip() 
    x6 = WeeklyPlan["x6"].str.rstrip()
    x7 = WeeklyPlan["x7"].str.rstrip() 
    # 如果数字是0结尾的就改成2位浮点,也就是保留0
    def format_number(num):
        # 检查数字是否是整数或以0结尾的小数
        if isinstance(num, int) or (isinstance(num, float) and num.is_integer()):
            return str(int(num))
        elif isinstance(num, str):
            try:
                num = float(num)
                if num.is_integer():
                    return str(int(num))
                else:
                    return f"{num:.2f}"
            except ValueError:
                return num  # 如果无法转换为浮点数,则返回原始字符串
        else:
            return f"{num:.2f}"

    # 遍历excel行,逐个生成
    for i in range(row_idx-1, row_idx):
        context = {
            "week": int(week[i][1:-1]),
            "year1": year1[i],
            "year2": year2[i],
            "month1": month1[i],
            "month2": month2[i],
            "day11": day11[i],
            "day22": day22[i],
            "day1": format_number(day1[i]),
            "day2": format_number(day2[i]),
            "day3": format_number(day3[i]), 
            "day4": format_number(day4[i]),
            "day5": format_number(day5[i]),
            "day6": format_number(day6[i]),
            "day7": format_number(day7[i]),          
            "x1":  format_number(x1[i]),
            "x2": format_number(x2[i]),
            "x3": format_number(x3[i]),
            "x4": format_number(x4[i]),
            "x5": format_number(x5[i]),
            "x6": format_number(x6[i]),
            "x7": format_number(x7[i]),
        }        
        tpl.render(context)
    #         # 假设 weekshu[i] 是类似于 '4、5' 或 '7' 这样的字符串

        # if isinstance(week[i], str) and len(week[i]) >= 3:  
            # week_part1 = str(week[i]).split('、')[0]  # 分割字符串并取第一部分
            # week_number1 = int(week_part)  # 转换为整数
            # week_number2=week_number1+1  
            # formatted_week_number = '%02d' % week_number1+'_'+'%02d' % week_number2 
            # tpl.save(file_path+fr"\ 第{str(week[i][1:-1])}周 每周安排.docx")
            # .docx")
    

        if (day7[i]) =='':
            day1[i]
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~).docx")

        else:
            tpl.save(new + fr"\{str(week[i])} 每周安排 ({month1[i]}.{day11[i]}~{month2[i]}.{day22[i]}).docx")


        # else:
        #     tpl.save(file_path+fr"\{weekshu[i]:02} 第{str(week[i][1:-1])}周 每周安排 ({day1[i]}+'~'+{day7[i]}).docx")

# 把nan(空值)删除
import os
from docx import Document

folder_path = new
# y=['A','nan']
# z=['.','']
# for s in range(len(y)):
for filename in os.listdir(folder_path):
    if filename.endswith('.docx'):
        file_path = os.path.join(folder_path, filename)
        doc = Document(file_path)
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    if cell.text == 'nan':
                        cell.text = ''
                        
        doc.save(file_path)
        print(f"Processed {filename}")



起止日期正确——3.30、6.30表述正确

本学期第20周只有一天,应该与19周合并,但这样我又要做一个8天的WORD模版了

最后还是在19周基础上,手动做了19.20周的模版

打包发送


http://www.kler.cn/a/547766.html

相关文章:

  • SYN-TFO伪造攻击.c
  • 算法面试题
  • 17.企业级知识图谱中的知识库全景解析(基本概念、 5W2H视角知识库、存储格式分类与技术对比、实践路径与架构设计、案例)
  • 《On Java中文版基础卷+进阶卷》
  • typecho快速发布文章
  • Acwing-基础算法课笔记之基础算法(双指针)
  • 系统不是基于UEFI的win11,硬盘格式MBR,我如何更改为GPT模式添加UEFI启动?
  • 借助天工AI 生成产品彩页体验 (5G 远距CPE产品彩页)
  • Centos搭建python环境
  • 【Qt】之【Linux】linux下实现开机自启Qt应用程序
  • 获取网站君子协议(robots协议)
  • 深入解析HTTP OPTIONS请求与JAX-RS实现
  • Kotlin 优雅的接口实现
  • 【Logistic Regression】机器学习中的基础分类模型
  • SpringAI集成DeepSeek实战
  • 【信息学奥赛一本通 C++题解】1258:【例9.2】数字金字塔
  • 鸿蒙next开发-struct如何封装共用模块
  • vue若依框架dicts中字典项的使用:表格展示与下拉框示例
  • C++ 中的栈与堆:区别与使用场景详解
  • 如何设置 Nginx 连接超时并进行测试(Nginx优化)