【办公类-16-07】“校历(月日(去0)+含星期)”(python 排班表系列)2022年上学期校历+2022下学期校历

效果展示:

2022学年上学期校历(2022-09-01——2023-01-17)

2022学年下学期校历(2023-02-15—2023-06-30)

背景需求:

    网上校历通常的每个格子,只显示一个”日“,初看,并不知道这是哪个月的”日“。

     上一篇实现了”校历“中的”日(D)“变成”月/日(MM/DD)的样式,效果如下:

CSDNhttps://mp.csdn.net/mp_blog/creation/editor/127234880

存在问题;

但是实际运用中,这个表格也有问题:

1、需要知道星期:虽然看到“月日”,但不知道星期几,需要向上查找

2、月日不含有0:月日表示"MM/DD"(两位数),一些含0的日期,我更习惯于看没有0的样式(如10/09、01/13  ,我希望它的展示方式是10/9、1/13)

针对这两个需求,我重新设计代码

重修代码:


# https://www.cnblogs.com/gradyblog/p/16457279.html
from contextlib import nullcontext
import datetime
import sys
import random
from tkinter import dnd
import xlrd
import xlwt
from openpyxl import load_workbook
import xlrd
import xlwt
import time
import datetime

'''20221015校历七天 有日期 +星期(上下学期都测过)'''

start=input('本学期开始的日期,输入样例(2022-09-01)\n')
end=input('本学期结束的日期,输入样例(2023-01-17)\n')
begin=int(input('开始日期前空几(周1周2周3 一共3天)\n'))
last=int(input('结束日期后留几天空白(5天)\n'))
weeksday=int(input('本学期共有几周(如21周)\n'))
title=input('生成xls的文件名称\n')

print('------------第1步:生成年月日列表(前后有空日)------------')

def date_generate(start_date, end_date):
    # print(f'Hi, {start_date}, {end_date}')
    start_dt = datetime.datetime.strptime(start_date, "%Y-%m-%d")
    end_dt = datetime.datetime.strptime(end_date, "%Y-%m-%d")
    next_dt = start_dt

    date_list = []  

    while next_dt <= end_dt:
        # next_dt_str = next_dt.strftime("%Y-%m-%d")
        # next_dt_str = next_dt.strftime("%m/%d")
        # next_dt_str = next_dt.strftime("%m/%d")
        next_dt_str = next_dt.strftime("%#m/%#d")
        # print(next_dt_str)
        date_list.append(next_dt_str)
        next_dt = next_dt + datetime.timedelta(days=1)
        
    print(date_list)
        
     #生成全部需要的列表 ['2022-09-01', '2022-09-02', '2022-09-03', '2022-09-04', '2022-09-05', '2022-09-06', '2022-09-07', '2022-09-08', '2022-09-09', '2022-09-10', '2022-09-11', '2022-09-12', '2022-09-13', '2022-09-14', '2022-09-15', '2022-09-16', '2022-09-17', '2022-09-18', '2022-09-19', '2022-09-20', '2022-09-21', '2022-09-22', '2022-09-23', '2022-09-24', '2022-09-25', '2022-09-26', '2022-09-27', '2022-09-28', '2022-09-29', '2022-09-30', '2022-10-01', '2022-10-02', '2022-10-03', '2022-10-04', '2022-10-05', '2022-10-06', '2022-10-07', '2022-10-08', '2022-10-09', '2022-10-10', '2022-10-11', '2022-10-12', '2022-10-13', '2022-10-14', '2022-10-15', '2022-10-16', '2022-10-17', '2022-10-18', '2022-10-19', '2022-10-20', '2022-10-21', '2022-10-22', '2022-10-23', '2022-10-24', '2022-10-25', '2022-10-26', '2022-10-27', '2022-10-28', '2022-10-29', '2022-10-30', '2022-10-31', '2022-11-01', '2022-11-02', '2022-11-03', '2022-11-04', '2022-11-05', '2022-11-06', '2022-11-07', '2022-11-08', '2022-11-09', '2022-11-10', '2022-11-11', '2022-11-12', '2022-11-13', '2022-11-14', '2022-11-15', '2022-11-16', '2022-11-17', '2022-11-18', '2022-11-19', '2022-11-20', '2022-11-21', '2022-11-22', '2022-11-23', '2022-11-24', '2022-11-25', '2022-11-26', '2022-11-27', '2022-11-28', '2022-11-29', '2022-11-30', '2022-12-01', '2022-12-02', '2022-12-03', '2022-12-04', '2022-12-05', '2022-12-06', '2022-12-07', '2022-12-08', '2022-12-09', '2022-12-10', '2022-12-11', '2022-12-12', '2022-12-13', '2022-12-14', '2022-12-15', '2022-12-16', '2022-12-17', '2022-12-18', '2022-12-19', '2022-12-20', '2022-12-21', '2022-12-22', '2022-12-23', '2022-12-24', '2022-12-25', '2022-12-26', '2022-12-27', '2022-12-28', '2022-12-29', '2022-12-30', '2022-12-31', '2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05', '2023-01-06', '2023-01-07', '2023-01-08', '2023-01-09', '2023-01-10', '2023-01-11', '2023-01-12', '2023-01-13', '2023-01-14', '2023-01-15', '2023-01-16', '2023-01-17', '', '', '', '', '', '', '']


    print('------------第2步:生成(星期),把星期补在日期旁边------------')
    weeks2=[]
    weeks= ['(一)','(二)','(三)','(四)','(五)','(六)','(日)',]   
    
    # 把星期'(一)''(二)'做成很长很长的列表,便于取值
    for j in range(0,weeksday):
        for k in weeks:
            weeks2.append(k)
    print(weeks2)
    # ['(一)', '(二)', '(三)', '(四)', '(五)', '(六)', '(日)', '(一)', '(二)', '(三)', '(四)', '(五)', '(六)', '(日)', '(一)', '(二)', '(三)', '(四)', '(五)', '(六)', '(日)', '(一)', '(二)', '(三)', '( 
    # 四)', '(五)', '(六)', '(日)', '(一)', '(二)', '(三)', '(四)', '(五)', '(六)', '(日)', '(一)', '(二)', '(三)', '(四)',


    date_week=[]  

    # 先在date_week最前面加3个空值,然后加上日期和星期合并
    for x in range(begin):        # 日期开始前加几个空值,替代8月29日8月30日8月31日
        b=''
        date_week.append(b)
    print(date_week)   
    # date_week=['', '', ''] q

    # 计算共有几天
    d1 = datetime.date(int(start.split("-")[0]), int(start.split("-")[1]), int(start.split("-")[2]))
    d2 = datetime.date(int(end.split("-")[0]), int(end.split("-")[1]), int(end.split("-")[2]))
    time=(d2 - d1).days+1
    print(time)
    # 要生成(135+1)个日期
    
    # 第1-21周的"日期"和"星期"合并
    for s in range(0,time):        # 一共21周*7-头空3天-尾空5天=139天
        c=date_list[s]+weeks2[s+begin]        # "日期"和"星期"合并
        date_week.append(c)
    print(date_week)
    # ['', '', '','09/01(四)', '09/02(五)', '09/03(六)', '09/04(日)', '09/05(一)', '09/06(二)', '09/07(三)', '09/08(四)', '09/09(五)', '09/10(六)', '09/11(日)', '09/12(一)', '09/13(二)', '09/14(三)', '09/15(四)', 
    # '09/16(五)', '09/17(六)', '09/18(日)', '09/19(一)', '09/20(二)', '09/21(三)', '09/22(四)', '09/23(五)', '09/24(六)', '09/25(日)', '09/26(一)', '09/27(二)', '09/28(三)', '09/29(四)', '09/30(五)', '10/01(六)', '10/02(日)
    
    #  最后在date_week的后面加5个kong           
    for x in range(last):        # 日期结束后加几个空值,以免重新开始选取d
        b=''
        date_week.append(b)
    print(date_week)  
    #   前空3  ['', '', '', '09/01(四)', '09/02(五)', '09/03(六)', '09/04(日)', '09/05(一)', '09/06(二)', '09/07(三)', '09/08(四)', '09/09(五)', '09/10(六)', '09/11(日)', '09/12(一)', '09/13(二)', '09/14(三)', '09/15(四)', '09/16(五)', '09/17(六)', '09/18(日)', '09/19(一)', '09/20(二)', '09/21(三)', '09/22(四)', '09/23(五)', '09/24(六)', '09/25(日)', '09/26(一)', '09/27(二)', '09/28(三)', '09/29(四)', '09/30(五)', '10/01(六)', '10/02(日)', '10/03(一)', '10/04(二)', '10/05(三)', '10/06(四)', '10/07(五)', '10/08(六)', '10/09(日)', '10/10(一)', '10/11(二)', '10/12(三)', '10/13(四)', '10/14(五)', '10/15(六)', '10/16(日)', '10/17(一)', '10/18(二)', '10/19(三)', '10/20(四)', '10/21(五)', '10/22(六)', '10/23(日)', '10/24(一)', '10/25(二)', '10/26(三)', '10/27(四)', '10/28(五)', '10/29(六)', '10/30(日)', '10/31(一)', '11/01(二)', '11/02(三)', '11/03(四)', '11/04(五)', '11/05(六)', '11/06(日)', '11/07(一)', '11/08(二)', '11/09(三)', '11/10(四)', '11/11(五)', '11/12(六)', '11/13(日)', '11/14(一)', '11/15(二)', '11/16(三)', '11/17(四)', '11/18(五)', '11/19(六)', '11/20(日)', '11/21(一)', '11/22(二)', '11/23(三)', '11/24(四)', '11/25(五)', '11/26(六)', '11/27(日)', '11/28(一)', '11/29(二)', '11/30(三)', '12/01(四)', '12/02(五)', '12/03(六)', '12/04(日)', '12/05(一)', '12/06(二)', '12/07(三)', '12/08(四)', '12/09(五)', '12/10(六)', '12/11(日)', '12/12(一)', '12/13(二)', '12/14(三)', '12/15(四)', '12/16(五)', '12/17(六)', '12/18(日)', '12/19(一)', '12/20(二)', '12/21(三)', '12/22(四)', '12/23(五)', '12/24(六)', '12/25(日)', '12/26(一)', '12/27(二)', '12/28(三)', '12/29( 
    # 四)', '12/30(五)', '12/31(六)', '01/01(日)', '01/02(一)', '01/03(二)', '01/04(三)', '01/05(四)', '01/06(五)', '01/07(六)', '01/08(日)', '01/09(一)', '01/10(二)', '01/11(三)', '01/12(四)', '01/13( 
    # 五)', '01/14(六)', '01/15(日)', '01/16(一)', '01/17(二)', '', '', '', '', '']后空5

 
    print('-----------第3步,每周都抽取7个日期(按周一到周日排列,不是校历图上的周日-周六排列)--------')
    list_date=[]# 取空列表
    # 第1-21周
    for p in range(0,weeksday):  #共21周    第1周索引取值,0-7,第2周索引 7-14,依次类推
        list_date.append(date_week[p*7:p*7+7])
    print(list_date)

    
    print('-----------第3步,保存到excle--------')
    # 以下是xls保存
    # arrlan= len(all)
    arrlan2 = len(list_date)# 日期抽取7天一组
    
    workbook = xlwt.Workbook()# 新建xls工作簿
    sheet = workbook.add_sheet("Sheet")# 新建xls工作簿的工作表的名字是sheet

    # 第0列 写入“第1周、第2周、第3周……第21周    
    dates=[]
    for i in range(1,weeksday+1):
        n="第{}周".format(i)    # 用遍历方法获得“第1周、第2周、第21周”字样,
        dates.append(n)          # 添加到列表    
    print(dates)        
    # print(date)

    row=1 # A2开始
    for d in range(0, len(dates)):
        sheet.write(row, 0, dates[d])         # 这里enumerate不能用,因为只有一列,所以就用
        row +=3   # 1=逐行写入,2=中间空一行,3=中间空2行
    row=2 # A3开始 再写一次第X周(备注用)
    for dd in range(0, len(dates)):
        sheet.write(row, 0, dates[dd])         # 这里enumerate不能用,因为只有一列,所以就用
        row +=3   # 1=逐行写入,2=中间空一行,3=中间空2行
    # row=3 # A4开始 再写一次第X周(备注用)
    # for ddd in range(0, len(dates)):
    #     sheet.write(row, 0, dates[ddd])         # 这里enumerate不能用,因为只有一列,所以就用
    #     row +=4   # 1=逐行写入,2=中间空一行,3=中间空2行
        

    # 第0行 写入 星期一  '星期二','星期三','星期四','星期五 ,'星期六','星期日'#
    weeks = ['周次','星期一','星期二','星期三','星期四','星期五','星期六','星期日']
    week = len(weeks) 

    col=0  # A1写入
    for d in range(0, len(weeks)):
        sheet.write(0,col,weeks[d])         # 因为只有一行,所以就用有两种写法(enumerate和这种)
        col+= 1  # 1=逐列写入,2=中间空一列,3=中间空2列2


    # B2 写入 7天日期(月日)
    row = 1
    for i in range(arrlan2):
        for col,item in enumerate(list_date[i],1):
            sheet.write(row,col,item)  
        row += 3

    # # B3 写入 5个5个的班级(中间空1个)
    # row = 2
    # for i in range(arrlan):
    #     for col,item in enumerate(z[i],1):
    #         sheet.write(row,col,item)  
    #     row += 3

    
    try:
        workbook.save(r"D:\test\{}.xls".format(title))    # 新建保存 只能xls
        print('计划生成成功')
    except e:
        print('失败...')
        print(e)

# Press the green button in the gutter to run the script.
# 定义起始日期和结束日期
if __name__ == '__main__':
    start_date = "{}".format(str(start))
    end_date = "{}".format(str(end))
    date_generate(start_date, end_date) 



重点解析:

1.日期+星期。(制作列表,把日期列表和星期列表合并)

(1)第1步:生成所有上学日期(去0的“月日”)

 (2)逐步添加date_week列表的内容(生成星期的长列表、逐步合并“3个空+日期星期+5个空”)

  (3)抽取每周7天,索引取值的优化(12行缩到2行)

 2.月日不要0。(在%m之间加一个#——%#m,%#d)就是这么简单

3、终端运行输入:

 终端显示内容

 

最终效果展示:

 感悟:

对于列表索引取值有了更深的理解。

可行性检验

前面做了”2022学年上学期的学历“,为了确保有实用性,再做”2022学年下学期的学历“

 效果:前空2

 后空0(20周的周六周日不显示,因为取值(0-139)正好到6月30日,后面没有日期了

 实验正面:这套代码能够通过输入起始日期和结束日期,生成带年月日期的校历(不考虑节假日)

实际运用案例——值班排班表

(1)运行生成7天日期、每周4次的值班班级

 (2)手动设计EXCEL表格,适合打印(删除周六、周日的日期、删除前3天、后5天的班次)

墙面展示:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,生成校历可以有不同的方式,以下是一种基本的实现方式: 1. 在 `pages` 目录下新建 `calendar` 文件夹,用于存放校历相关页面和组件。 2. 在 `calendar` 文件夹中新建 `calendar.vue` 文件,作为校历页面的入口文件。在该页面中,可以使用 `uni-calendar` 组件来显示校历。 ```html <template> <div class="calendar-container"> <uni-calendar :template="calendarTemplate"></uni-calendar> </div> </template> <script> import UniCalendar from '@/components/uni-calendar/uni-calendar.vue'; export default { components: { UniCalendar }, data() { return { calendarTemplate: 'schoolCalendar' } } } </script> ``` 在上述代码中,通过 `uni-calendar` 组件引入自定义历模板,并设置为 `schoolCalendar`。 3. 在 `calendar` 文件夹中新建 `schoolCalendar.vue` 文件,作为自定义历模板。在该模板中,可以设置校历的样式和显示内容。 ```html <template name="schoolCalendar"> <div class="school-calendar-container"> <div class="school-calendar-header"> <span class="school-calendar-title">{{title}}</span> </div> <div class="school-calendar-body"> <div class="school-calendar-weekdays"> <span v-for="weekday in weekdays">{{weekday}}</span> </div> <div class="school-calendar-days"> <div v-for="(month, index) in months" :key="index"> <div class="school-calendar-month">{{month.title}}</div> <div class="school-calendar-grid"> <div v-for="(day, index) in month.days" :key="index" class="school-calendar-day" :class="{'school-calendar-holiday': day.isHoliday}"> <div class="school-calendar-day-number">{{day.day}}</div> <div class="school-calendar-day-info">{{day.info}}</div> </div> </div> </div> </div> </div> </div> </template> <script> export default { props: { title: String, weekdays: Array, months: Array } } </script> <style lang="scss"> .school-calendar-container { background-color: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .school-calendar-header { height: 48px; line-height: 48px; text-align: center; font-size: 18px; font-weight: 500; color: #333; border-bottom: 1px solid #eee; } .school-calendar-body { padding: 12px; } .school-calendar-weekdays { display: flex; justify-content: space-between; margin-bottom: 12px; color: #999; font-size: 14px; } .school-calendar-days { display: flex; flex-wrap: wrap; } .school-calendar-month { width: 100%; text-align: center; font-size: 18px; font-weight: 500; color: #333; margin-bottom: 12px; } .school-calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; } .school-calendar-day { position: relative; height: 60px; background-color: #f5f5f5; border-radius: 4px; overflow: hidden; } .school-calendar-holiday { background-color: #f2dede; } .school-calendar-day-number { position: absolute; top: 0; left: 0; width: 24px; height: 24px; line-height: 24px; text-align: center; font-size: 14px; font-weight: 500; color: #333; background-color: #fff; border-radius: 50%; transform: translate(8px, 8px); } .school-calendar-day-info { position: absolute; bottom: 0; left: 0; right: 0; height: 20px; line-height: 20px; text-align: center; font-size: 12px; font-weight: 500; color: #999; } </style> ``` 在上述代码中,通过 `template` 标签定义自定义历模板的名称为 `schoolCalendar`,并设置校历的样式和显示内容。其中,`props` 中的数据为校历的标题、星期几的名称和份的数据,可以通过外部传递进来。 4. 在 `calendar` 文件夹中新建 `schoolCalendarData.js` 文件,用于存放校历的数据。 ```js export default { title: '2022校历', weekdays: ['', '一', '二', '三', '四', '五', '六'], months: [ { title: '1', days: [ {day: 1, isHoliday: true, info: '元旦'}, {day: 2, isHoliday: true}, {day: 3, isHoliday: true}, {day: 4}, {day: 5}, {day: 6}, {day: 7}, {day: 8}, {day: 9}, {day: 10}, {day: 11}, {day: 12}, {day: 13}, {day: 14}, {day: 15}, {day: 16}, {day: 17, isHoliday: true}, {day: 18}, {day: 19}, {day: 20}, {day: 21}, {day: 22}, {day: 23}, {day: 24}, {day: 25}, {day: 26}, {day: 27}, {day: 28}, {day: 29}, {day: 30}, {day: 31} ] }, // ... 其他份的数据 ] } ``` 在上述代码中,定义了校历的标题、星期几的名称和份的数据。 5. 在 `calendar.vue` 页面中引入 `schoolCalendarData.js` 文件,并将数据传递给自定义历模板。 ```html <template> <div class="calendar-container"> <uni-calendar :template="calendarTemplate" :data="calendarData"></uni-calendar> </div> </template> <script> import UniCalendar from '@/components/uni-calendar/uni-calendar.vue'; import schoolCalendarData from './schoolCalendarData.js'; export default { components: { UniCalendar }, data() { return { calendarTemplate: 'schoolCalendar', calendarData: schoolCalendarData } } } </script> ``` 在上述代码中,通过 `:data` 属性将 `schoolCalendarData.js` 中的数据传递给自定义历模板。 6. 在 `App.vue` 文件中注册 `uni-calendar` 组件和 `uni-calendar` 样式。 ```html <template> <view class="content"> <router-view></router-view> </view> </template> <script> import UniCalendar from '@/components/uni-calendar/uni-calendar.vue'; import '@/components/uni-calendar/uni-calendar.scss'; export default { components: { UniCalendar } } </script> ``` 在上述代码中,通过 `import` 引入 `uni-calendar` 组件和 `uni-calendar` 样式,并在组件中注册。 7. 运行项目,在 `calendar` 页面中即可显示校历。 以上是一种基本的校历生成方式,具体实现还需要根据项目的实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿夏reasonsummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值