【办公类-53-12】20261016(预测)Python模仿制作2026学年第二学期校历(excel+pdf,上下学期都包含)

一、背景需求

最近在制作中2班的"贴墙资料",周计划做了一周。

1.因为换了WPS电脑,重新写了"WPS版本"代码。过去是"微软office版本win32"

2.同时教案内容要手动黏贴到统一Word模版内,很费时。

3.以下csdn里面有大量的过程性的代码,如果下次再用这些代码,容易搞不清楚哪些是最后的代码。

【办公类-131-06】20261007中2班周计划制作(过程全记录)(Word{{字母}}模版展示+统一原始Word单元格位置+WPS)https://mp.csdn.net/mp_blog/creation/editor/167219055

所以我想把下学期的周计划也做一编,把最终的代码贴一遍。但做周计划最重要的是获取"上班时间",也就是制作校历。

二、2027年放假安排

问豆包要2027年放假安排,它说2026年11月国务院才会发布"2027年的节假日安排"

我记得我制作202609-202701上学期元旦节的放假安排就是通过对比前10年的元旦节放假安排,来预测2027年元旦的放假

三、修改代码

三个节,只有劳动节要换班

四、更改底纹黄色(日版和日月版)

python 复制代码
'''
"日"版
模仿制作2027年2月第二学期的校历(标注节假日)3月第一天是年月日,每月第1天是月日,其他都是日
上学期和下学期
星火讯飞、deepseek修订、阿夏
20270201
'''

from openpyxl import Workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
import datetime
import time, os
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.page import PageMargins
import win32com.client  # 用于 Excel 转 PDF

path = r'D:\Python最终内容\20270201校历'
os.makedirs(path,exist_ok=True)


title = '2026学年第二学期校历"日"版(阿夏20270201)'
m = 0  # 起始日期前空几天(周一开始,就是空0天)

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

# 设置页边距(单位为厘米)
left_margin_cm = 1.3
right_margin_cm = 1.3
top_margin_cm = 2
bottom_margin_cm = 2

# 将厘米转换为英寸
left_margin_inch = left_margin_cm * 0.393701
right_margin_inch = right_margin_cm * 0.393701
top_margin_inch = top_margin_cm * 0.393701
bottom_margin_inch = bottom_margin_cm * 0.393701

# 设置页边距
margins = PageMargins(left=left_margin_inch, right=right_margin_inch, 
                      top=top_margin_inch, bottom=bottom_margin_inch)
sheet.page_margins = margins

# 设置标题行
title_row = ["周次", "一", "二", "三", "四", "五", "六", "日"]
sheet.append(title_row)

# 设置日期范围
start_date = datetime.date(2027, 2, 22)# 2月22日是周一,不需要补一个周一的日期
end_date = datetime.date(2027, 6, 30)# 6月30日周三

# 生成日期列表并包含标题行和空格行
date_list = [title_row]
for i in range(m):
    date_list.append([''])  # 添加一个空格行

current_day = start_date
while current_day <= end_date:
    date_list.append([current_day])
    current_day += datetime.timedelta(days=1)

# # 上学期(9-1月)
# # 计算周数和将日期列表写入Excel
# current_week = 1
# for i in range(1, len(date_list), 7):
#     week_dates = date_list[i:i+7]
    
#     # 在A列中添加周次
#     sheet.cell(row=current_week + 1, column=1).value = f"第{current_week}周"
#     cell = sheet.cell(row=current_week + 1, column=1)
#     cell.alignment = Alignment(horizontal='center', vertical='center')
#     cell.font = Font(size=16)
#     # 添加第一列的边框
#     thin_border = Border(
#         left=Side(style='thin', color='000000'),
#         right=Side(style='thin', color='000000'),
#         top=Side(style='thin', color='000000'),
#         bottom=Side(style='thin', color='000000')
#     )
#     cell.border = thin_border
    
#     # 在正确的单元格中添加日期
#     for j in range(7):  # 确保遍历7天(即使数据不足7天)
#         cell = sheet.cell(row=current_week + 1, column=j + 2)
        
#         # 如果当前日期存在,则填充数据
#         if j < len(week_dates) and week_dates[j]:
#             date_obj = week_dates[j][0]
            
#             # 设置日期显示格式
#             # 第一天20260302
#             if date_obj.year == 2026 and date_obj.month == 9 and date_obj.day == 1:
#                 cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
                # ============新增下面两行============
                # cell.font = Font(name="宋体", size=12)
         
#             # 如果是每月第一天,就填写月日
#             elif date_obj.day == 1:
#                 cell.value = f"{date_obj.month}/{date_obj.day}"       
#                  # 劳动节假期(汉字) 是四月1日,需要年月 
                
#                 if date_obj.year == 2026 and date_obj.month == 10 and date_obj.day == 1:
#                     cell.value = f"{date_obj.month}/{date_obj.day}国庆"   
#                 if date_obj.year == 2027 and date_obj.month == 1 and date_obj.day == 1:
#                     cell.value = f"{date_obj.month}/{date_obj.day}元旦"       
                            
             
#             else:
#                 cell.value = f"{date_obj.day}"
#                 # 中秋假期(汉字)不是X月1日,就只要写日    
#                 if date_obj.year == 2026 and date_obj.month == 9 and date_obj.day in range(25, 26):
#                     cell.value = f"{date_obj.day}中秋"   

#                  # 国庆节假期(汉字)5月2-5日,就只要写日
#                 elif date_obj.year == 2026 and date_obj.month == 10 and date_obj.day in range(1, 2):
#                     cell.value = f"{date_obj.day}国庆"
               
#                  # 元旦节假期(汉字)    
#                 elif date_obj.year == 2027 and date_obj.month == 1 and date_obj.day in range(1, 2):
#                     cell.value = f"{date_obj.day}元旦"
            
#             # 特殊日期处理(国庆节和元旦)填充白色
#             is_special_date = False

#              # 中秋假期 (9月25-27日)
#             if date_obj.month == 9 and 25 <= date_obj.day <= 27:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
            
#             # 国庆节假期 (10月1-7日)
#             if date_obj.month == 10 and 1 <= date_obj.day <= 7:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色

#             # 元旦假期 (1月1-3日)
#             if date_obj.month == 1 and 1 <= date_obj.day <= 3:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
                

           
                
#             # 国定假日 补上班日 (中秋节补上班9月20日、国庆节补上班10月11日)
#             elif (date_obj.month == 9 and date_obj.day == 20) or \
#                  (date_obj.month == 10 and date_obj.day == 10) :
#                 #  (date_obj.month == 1 and date_obj.day == 4):            
#                 is_special_date = True
#                 if date_obj.month == 9:
#                     cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄
#                 elif date_obj.month == 10:
#                     cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红
#                 # elif date_obj.month == 1:
#                 #     cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘
            
#             #   # 周六周日调休日 (5月9日劳动节周六上班)
#             # elif (date_obj.month == 5 and date_obj.day == 9):
#             #     is_special_date = True
#             #     if date_obj.month == 5:
#             #         cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色

#             # 如果不是特殊日期,则按月份设置颜色
#             if not is_special_date:
#                 # 周末默认白色,除非是特殊日期
#                 if j >= 5:  # 周六(第6列)和周日(第7列)
#                     cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
#                 else:
#                     # 按月份设置颜色
#                     if date_obj.month == 9:
#                         cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄色
#                     if date_obj.month == 10:
#                         cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红色
#                     elif date_obj.month == 11:
#                         cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色
#                     elif date_obj.month == 12:
#                         cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色
#                     elif date_obj.month == 1:
#                         cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘色
        
        # 无论是否有数据,都设置边框
        # thin_border = Border(
        #     left=Side(style='thin', color='000000'),
        #     right=Side(style='thin', color='000000'),
        #     top=Side(style='thin', color='000000'),
        #     bottom=Side(style='thin', color='000000')
        # )
        # # cell.border = thin_border
        # # cell.alignment = Alignment(horizontal='center', vertical='center')
        # # cell.font = Font(size=16)

        # cell.border = thin_border
        # cell.alignment = Alignment(horizontal='center', vertical='center')
        # # 开学第一天已经单独设置宋体14,其余日期用size16
        # if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
        #     cell.font = Font(size=16)
    
    # current_week += 1

# 下学期
# 计算周数和将日期列表写入Excel
current_week = 1
for i in range(1, len(date_list), 7):
    week_dates = date_list[i:i+7]
    
    # 在A列中添加周次
    sheet.cell(row=current_week + 1, column=1).value = f"第{current_week}周"
    cell = sheet.cell(row=current_week + 1, column=1)
    cell.alignment = Alignment(horizontal='center', vertical='center')
    cell.font = Font(size=16)
    # 添加第一列的边框
    thin_border = Border(
        left=Side(style='thin', color='000000'),
        right=Side(style='thin', color='000000'),
        top=Side(style='thin', color='000000'),
        bottom=Side(style='thin', color='000000')
    )
    cell.border = thin_border
    
    # 在正确的单元格中添加日期
    for j in range(7):  # 确保遍历7天(即使数据不足7天)
        cell = sheet.cell(row=current_week + 1, column=j + 2)
        
        # 如果当前日期存在,则填充日期数字
        if j < len(week_dates) and week_dates[j]:
            date_obj = week_dates[j][0]
            
            # 设置日期显示格式
            # 第一天20260302
            if date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22:
                cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
                # ============新增下面两行============
                cell.font = Font(name="宋体", size=12)
         
            # 如果节假日是每月第一天,就填写月日
            elif date_obj.day == 1:
                cell.value = f"{date_obj.month}/{date_obj.day}"       
                
                 # 劳动节假期(汉字) 是5月1日,需要年月   5月1日              
                if date_obj.year == 2027 and date_obj.month == 5 and date_obj.day == 1:
                    cell.value = f"{date_obj.month}/{date_obj.day}劳动"         
                            
            #   如果节假日不是每月第一天,就填写日
            else:
                cell.value = f"{date_obj.day}"
                # 清明节假期(汉字)不是4月1日,就只要写日    4月3-5日
                if date_obj.year == 2027 and date_obj.month == 4 and date_obj.day in range(3, 6):
                    cell.value = f"{date_obj.day}清明"   

                 # 劳动节假期(汉字)5月2-5日,就只要写日  5月2日-5日
                elif date_obj.year == 2027 and date_obj.month == 5 and date_obj.day in range(2, 6):
                    cell.value = f"{date_obj.day}劳动"
               
                 # 端午节假期(汉字)     6月9日一天
                elif date_obj.year == 2027 and date_obj.month == 6 and date_obj.day in range(9,10 ):
                    cell.value = f"{date_obj.day}端午"
            
            # 特殊日期处理(国庆节和元旦)填充白色
            is_special_date = False

             # 清明节假期 (4月3-5日)
            if date_obj.month == 4 and 3 <= date_obj.day <= 5:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅橘色
            
            # 劳动节假期 (5月1-5日)
            if date_obj.month == 5 and 1 <= date_obj.day <= 5:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅红色

            # 端午假期 (6月9日)
            # if date_obj.month == 6 and 19 <= date_obj.day <= 21:
            if date_obj.month == 6 and date_obj.day == 9:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅红色              

           
                       
              #  # 国定假日 补上班日 (中秋节补上班9月20日、国庆节补上班10月11日)**劳动节**
            #劳动节: 5 月 1 日(周六)‑5 月 5 日(周三)放假 5 天。
            # 预计补班:**4 月 25 日(周日)、5 月 8 日(周六)上班**。

            elif (date_obj.month == 4 and date_obj.day == 25):
                is_special_date = True
            # elif date_obj.month == 4:
                cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色

            elif (date_obj.month == 5 and date_obj.day == 8):
                is_special_date = True
            # elif date_obj.month == 5:
                cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色

            # 如果不是特殊日期,则按月份设置颜色
            if not is_special_date:
                # 周末默认白色,除非是特殊日期
                if j >= 5:  # 周六(第6列)和周日(第7列)
                    cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
                else:
                    # 按月份设置颜色
                    if date_obj.month == 2:
                        cell.fill = PatternFill(start_color="FFFF96", end_color="FFFF96", fill_type="solid")  # 明黄色(RGB  B的颜色下降)
                        # cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄色(原始)
                        # cell.fill = PatternFill(start_color="CCCC00", end_color="CCCC00", fill_type="solid")  # 黄绿色
                        # cell.fill = PatternFill(start_color="BBBB00", end_color="BBBB00", fill_type="solid")  # 深黄绿色
                        # cell.fill = PatternFill(start_color="AAAA00", end_color="AAAA00", fill_type="solid")  # 深深黄绿色
                        # cell.fill = PatternFill(start_color="D4AA00", end_color="D4AA00", fill_type="solid")  # 金黄色(棕黄色)

                        # cell.fill = PatternFill(start_color="E6D000", end_color="E6D000", fill_type="solid")  # 亮土黄色
                        # cell.fill = PatternFill(start_color="D9C200", end_color="D9C200", fill_type="solid")  #  亮土黄色
                        # cell.fill = PatternFill(start_color="F2DD00", end_color="F2DD00", fill_type="solid")  # 亮黄色
                        # cell.fill = PatternFill(start_color="E6C800", end_color="E6C800", fill_type="solid")  # 金黄
                        # cell.fill = PatternFill(start_color="CCB200", end_color="CCB200", fill_type="solid")  # 土黄色
                        

                    if date_obj.month == 3:
                        cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红色
                    elif date_obj.month == 4:
                        cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色
                    elif date_obj.month == 5:
                        cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色
                    elif date_obj.month == 6:
                        cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘色
        
        # 无论是否有数据,都设置边框
        thin_border = Border(
            left=Side(style='thin', color='000000'),
            right=Side(style='thin', color='000000'),
            top=Side(style='thin', color='000000'),
            bottom=Side(style='thin', color='000000')
        )
        # cell.border = thin_border
        # cell.alignment = Alignment(horizontal='center', vertical='center')
        # cell.font = Font(size=16)

        cell.border = thin_border
        cell.alignment = Alignment(horizontal='center', vertical='center')
        # 开学第一天已经单独设置宋体14,其余日期用size16

        if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
            cell.font = Font(size=16)
    
    
    current_week += 1

# 设置标题行样式
for col in range(1, len(title_row) + 1):
    cell = sheet.cell(row=1, column=col)
    cell.alignment = Alignment(horizontal='center', vertical='center')
    thin_border = Border(
        left=Side(style='thin', color='000000'),
        right=Side(style='thin', color='000000'),
        top=Side(style='thin', color='000000'),
        bottom=Side(style='thin', color='000000')
    )
    cell.border = thin_border
    cell.fill = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid")  # 浅蓝色
    cell.font = Font(size=16)

# 设置行高和列宽
for row in range(1, sheet.max_row + 2):
    sheet.row_dimensions[row].height = 30

# 特别确保最后一行高度为30
sheet.row_dimensions[sheet.max_row].height = 30

for col in range(1, sheet.max_column + 1):
    column_letter = get_column_letter(col)
    sheet.column_dimensions[column_letter].width = 11.5

# 添加标题行
sheet.insert_rows(1)
sheet.merge_cells('A1:H1')
sheet.cell(row=1, column=1).value = title
sheet.cell(row=1, column=1).alignment = Alignment(horizontal='center', vertical='center')
sheet.cell(row=1, column=1).font = Font(size=18, bold=True)
sheet.cell(row=1, column=1).fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid") 

# 保存工作簿
excel_file = path + fr"\00-03 {title}.xlsx"
workbook.save(excel_file)
print(f"校历已生成: {excel_file}")

# ========== 转换为 PDF ==========
def excel_to_pdf(input_excel_path, output_pdf_path):
    try:
        # 启动 Excel 应用程序
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False  # 不显示 Excel 界面
        
        # 打开 Excel 文件
        workbook = excel.Workbooks.Open(input_excel_path)
        
        # 设置打印区域(整个工作表)
        sheet = workbook.ActiveSheet
        sheet.PageSetup.Zoom = False
        sheet.PageSetup.FitToPagesWide = 1  # 适应宽度到 1 页
        sheet.PageSetup.FitToPagesTall = False  # 高度不限制
        
        # 导出为 PDF
        workbook.ExportAsFixedFormat(0, output_pdf_path)  # 0 表示 PDF 格式
        
        # 关闭 Excel
        workbook.Close(False)
        excel.Quit()
        
        print(f"PDF 已生成: {output_pdf_path}")
    except Exception as e:
        print(f"转换失败: {e}")

# 调用转换函数
pdf_file = path + fr"\00-03 {title}.pdf"
excel_to_pdf(excel_file, pdf_file)

time.sleep(2)

"FFFFCC"

我还是喜欢原始的明黄色

这个黄色还是不好看,FFFFCC(明黄色)

同理制作日月版

python 复制代码
'''
"月日"版
模仿制作2027年2月第二学期的校历(标注节假日)3月第一天是年月日,每月第1天是月日,其他都是日
上学期和下学期
星火讯飞、deepseek修订、阿夏
20270201
'''

from openpyxl import Workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
import datetime
import time, os
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.page import PageMargins
import win32com.client  # 用于 Excel 转 PDF

path = r'D:\Python最终内容\20270201校历'
os.makedirs(path,exist_ok=True)


title = '2026学年第二学期校历"月日"版(阿夏20270201)'
m = 0  # 起始日期前空几天(周一开始,就是空0天)

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

# 设置页边距(单位为厘米)
left_margin_cm = 1.3
right_margin_cm = 1.3
top_margin_cm = 2
bottom_margin_cm = 2

# 将厘米转换为英寸
left_margin_inch = left_margin_cm * 0.393701
right_margin_inch = right_margin_cm * 0.393701
top_margin_inch = top_margin_cm * 0.393701
bottom_margin_inch = bottom_margin_cm * 0.393701

# 设置页边距
margins = PageMargins(left=left_margin_inch, right=right_margin_inch, 
                      top=top_margin_inch, bottom=bottom_margin_inch)
sheet.page_margins = margins

# 设置标题行
title_row = ["周次", "一", "二", "三", "四", "五", "六", "日"]
sheet.append(title_row)

# 设置日期范围
start_date = datetime.date(2027, 2, 22)# 2月22日是周一,不需要补一个周一的日期
end_date = datetime.date(2027, 6, 30)# 6月30日周三

# 生成日期列表并包含标题行和空格行
date_list = [title_row]
for i in range(m):
    date_list.append([''])  # 添加一个空格行

current_day = start_date
while current_day <= end_date:
    date_list.append([current_day])
    current_day += datetime.timedelta(days=1)

# # 上学期(9-1月)
# # 计算周数和将日期列表写入Excel
# current_week = 1
# for i in range(1, len(date_list), 7):
#     week_dates = date_list[i:i+7]
    
#     # 在A列中添加周次
#     sheet.cell(row=current_week + 1, column=1).value = f"第{current_week}周"
#     cell = sheet.cell(row=current_week + 1, column=1)
#     cell.alignment = Alignment(horizontal='center', vertical='center')
#     cell.font = Font(size=16)
#     # 添加第一列的边框
#     thin_border = Border(
#         left=Side(style='thin', color='000000'),
#         right=Side(style='thin', color='000000'),
#         top=Side(style='thin', color='000000'),
#         bottom=Side(style='thin', color='000000')
#     )
#     cell.border = thin_border
    
#     # 在正确的单元格中添加日期
#     for j in range(7):  # 确保遍历7天(即使数据不足7天)
#         cell = sheet.cell(row=current_week + 1, column=j + 2)
        
#         # 如果当前日期存在,则填充数据
#         if j < len(week_dates) and week_dates[j]:
#             date_obj = week_dates[j][0]
            
#             # 设置日期显示格式
#             # 第一天20260302
#             if date_obj.year == 2026 and date_obj.month == 9 and date_obj.day == 1:
#                 cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
#               ============新增下面两行============
#               cell.font = Font(name="宋体", size=12)
         
#             # 如果是每月第一天,就填写月日
#             elif date_obj.day == 1:
#                 cell.value = f"{date_obj.month}/{date_obj.day}"       
#                  # 劳动节假期(汉字) 是四月1日,需要年月 
                
#                 if date_obj.year == 2026 and date_obj.month == 10 and date_obj.day == 1:
#                     cell.value = f"{date_obj.month}/{date_obj.day}国庆"   
#                 if date_obj.year == 2027 and date_obj.month == 1 and date_obj.day == 1:
#                     cell.value = f"{date_obj.month}/{date_obj.day}元旦"       
                            
             
#             else:
#                 cell.value = f"{date_obj.month}/{date_obj.day}"
#                 # 中秋假期(汉字)不是X月1日,就只要写日    
#                 if date_obj.year == 2026 and date_obj.month == 9 and date_obj.day in range(25, 26):
#                     cell.value = f"{date_obj.month}/{date_obj.day}中秋"   

#                  # 国庆节假期(汉字)5月2-5日,就只要写日
#                 elif date_obj.year == 2026 and date_obj.month == 10 and date_obj.day in range(1, 2):
#                     cell.value = f"{date_obj.month}/{date_obj.day}国庆"
               
#                  # 元旦节假期(汉字)    
#                 elif date_obj.year == 2027 and date_obj.month == 1 and date_obj.day in range(1, 2):
#                     cell.value = f"{date_obj.month}/{date_obj.day}元旦"
            
#             # 特殊日期处理(国庆节和元旦)填充白色
#             is_special_date = False

#              # 中秋假期 (9月25-27日)
#             if date_obj.month == 9 and 25 <= date_obj.day <= 27:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
            
#             # 国庆节假期 (10月1-7日)
#             if date_obj.month == 10 and 1 <= date_obj.day <= 7:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色

#             # 元旦假期 (1月1-3日)
#             if date_obj.month == 1 and 1 <= date_obj.day <= 3:
#                 is_special_date = True
#                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
                

           
                
#             # 国定假日 补上班日 (中秋节补上班9月20日、国庆节补上班10月11日)
#             elif (date_obj.month == 9 and date_obj.day == 20) or \
#                  (date_obj.month == 10 and date_obj.day == 10) :
#                 #  (date_obj.month == 1 and date_obj.day == 4):            
#                 is_special_date = True
#                 if date_obj.month == 9:
#                     cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄
#                 elif date_obj.month == 10:
#                     cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红
#                 # elif date_obj.month == 1:
#                 #     cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘
            
#             #   # 周六周日调休日 (5月9日劳动节周六上班)
#             # elif (date_obj.month == 5 and date_obj.day == 9):
#             #     is_special_date = True
#             #     if date_obj.month == 5:
#             #         cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色

#             # 如果不是特殊日期,则按月份设置颜色
#             if not is_special_date:
#                 # 周末默认白色,除非是特殊日期
#                 if j >= 5:  # 周六(第6列)和周日(第7列)
#                     cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
#                 else:
#                     # 按月份设置颜色
#                     if date_obj.month == 9:
#                         cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄色
#                     if date_obj.month == 10:
#                         cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红色
#                     elif date_obj.month == 11:
#                         cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色
#                     elif date_obj.month == 12:
#                         cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色
#                     elif date_obj.month == 1:
#                         cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘色
        
#         # 无论是否有数据,都设置边框
#         thin_border = Border(
#             left=Side(style='thin', color='000000'),
#             right=Side(style='thin', color='000000'),
#             top=Side(style='thin', color='000000'),
#             bottom=Side(style='thin', color='000000')
#         )
        # # cell.border = thin_border
        # # cell.alignment = Alignment(horizontal='center', vertical='center')
        # # cell.font = Font(size=16)

        # cell.border = thin_border
        # cell.alignment = Alignment(horizontal='center', vertical='center')
        # # 开学第一天已经单独设置宋体14,其余日期用size16
        # if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
        #     cell.font = Font(size=16)
    
#     current_week += 1

# 下学期
# 计算周数和将日期列表写入Excel
current_week = 1
for i in range(1, len(date_list), 7):
    week_dates = date_list[i:i+7]
    
    # 在A列中添加周次
    sheet.cell(row=current_week + 1, column=1).value = f"第{current_week}周"
    cell = sheet.cell(row=current_week + 1, column=1)
    cell.alignment = Alignment(horizontal='center', vertical='center')
    cell.font = Font(size=16)
    # 添加第一列的边框
    thin_border = Border(
        left=Side(style='thin', color='000000'),
        right=Side(style='thin', color='000000'),
        top=Side(style='thin', color='000000'),
        bottom=Side(style='thin', color='000000')
    )
    cell.border = thin_border
    
    # 在正确的单元格中添加日期
    for j in range(7):  # 确保遍历7天(即使数据不足7天)
        cell = sheet.cell(row=current_week + 1, column=j + 2)
        
        # 如果当前日期存在,则填充日期数字
        if j < len(week_dates) and week_dates[j]:
            date_obj = week_dates[j][0]
            
            # 设置日期显示格式
            # 第一天20260302
            if date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22:
                cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
                #  ============新增下面两行============
                cell.font = Font(name="宋体", size=12)
         
            # 如果节假日是每月第一天,就填写月日
            elif date_obj.day == 1:
                cell.value = f"{date_obj.month}/{date_obj.day}"       
                
                 # 劳动节假期(汉字) 是5月1日,需要年月   5月1日              
                if date_obj.year == 2027 and date_obj.month == 5 and date_obj.day == 1:
                    cell.value = f"{date_obj.month}/{date_obj.day}劳动"         
                            
            #   如果节假日不是每月第一天,就填写日
            else:
                cell.value = f"{date_obj.month}/{date_obj.day}"
                # 清明节假期(汉字)不是4月1日,就只要写日    4月3-5日
                if date_obj.year == 2027 and date_obj.month == 4 and date_obj.day in range(3, 6):
                    cell.value = f"{date_obj.month}/{date_obj.day}清明"   

                 # 劳动节假期(汉字)5月2-5日,就只要写日  5月2日-5日
                elif date_obj.year == 2027 and date_obj.month == 5 and date_obj.day in range(2, 6):
                    cell.value = f"{date_obj.month}/{date_obj.day}劳动"
               
                 # 端午节假期(汉字)     6月9日一天
                elif date_obj.year == 2027 and date_obj.month == 6 and date_obj.day in range(9,10 ):
                    cell.value = f"{date_obj.month}/{date_obj.day}端午"
            
            # 特殊日期处理(国庆节和元旦)填充白色
            is_special_date = False

             # 清明节假期 (4月3-5日)
            if date_obj.month == 4 and 3 <= date_obj.day <= 5:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅橘色
            
            # 劳动节假期 (5月1-5日)
            if date_obj.month == 5 and 1 <= date_obj.day <= 5:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅红色

            # 端午假期 (6月9日)
            # if date_obj.month == 6 and 19 <= date_obj.day <= 21:
            if date_obj.month == 6 and date_obj.day == 9:
                is_special_date = True
                cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 浅红色              

           
                       
              #  # 国定假日 补上班日 (中秋节补上班9月20日、国庆节补上班10月11日)**劳动节**
            #劳动节: 5 月 1 日(周六)‑5 月 5 日(周三)放假 5 天。
            # 预计补班:**4 月 25 日(周日)、5 月 8 日(周六)上班**。

            elif (date_obj.month == 4 and date_obj.day == 25):
                is_special_date = True
            # elif date_obj.month == 4:
                cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色

            elif (date_obj.month == 5 and date_obj.day == 8):
                is_special_date = True
            # elif date_obj.month == 5:
                cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色

            # 如果不是特殊日期,则按月份设置颜色
            if not is_special_date:
                # 周末默认白色,除非是特殊日期
                if j >= 5:  # 周六(第6列)和周日(第7列)
                    cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")  # 白色
                else:
                    # 按月份设置颜色
                    if date_obj.month == 2:
                        cell.fill = PatternFill(start_color="FFFF96", end_color="FFFF96", fill_type="solid")  # 明黄色(RGB  B的颜色下降)
                        # cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")  # 浅黄色(原始)
                        # cell.fill = PatternFill(start_color="CCCC00", end_color="CCCC00", fill_type="solid")  # 黄绿色
                        # cell.fill = PatternFill(start_color="BBBB00", end_color="BBBB00", fill_type="solid")  # 深黄绿色
                        # cell.fill = PatternFill(start_color="AAAA00", end_color="AAAA00", fill_type="solid")  # 深深黄绿色
                        # cell.fill = PatternFill(start_color="D4AA00", end_color="D4AA00", fill_type="solid")  # 金黄色(棕黄色)

                        # cell.fill = PatternFill(start_color="E6D000", end_color="E6D000", fill_type="solid")  # 亮土黄色
                        # cell.fill = PatternFill(start_color="D9C200", end_color="D9C200", fill_type="solid")  #  亮土黄色
                        # cell.fill = PatternFill(start_color="F2DD00", end_color="F2DD00", fill_type="solid")  # 亮黄色
                        # cell.fill = PatternFill(start_color="E6C800", end_color="E6C800", fill_type="solid")  # 金黄
                        # cell.fill = PatternFill(start_color="CCB200", end_color="CCB200", fill_type="solid")  # 土黄色
                        

                    if date_obj.month == 3:
                        cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")  # 浅红色
                    elif date_obj.month == 4:
                        cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")  # 浅绿色
                    elif date_obj.month == 5:
                        cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")  # 浅灰色
                    elif date_obj.month == 6:
                        cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")  # 浅橘色
        
        # 无论是否有数据,都设置边框
        thin_border = Border(
            left=Side(style='thin', color='000000'),
            right=Side(style='thin', color='000000'),
            top=Side(style='thin', color='000000'),
            bottom=Side(style='thin', color='000000')
        )
        # cell.border = thin_border
        # cell.alignment = Alignment(horizontal='center', vertical='center')
        # cell.font = Font(size=16)

        cell.border = thin_border
        cell.alignment = Alignment(horizontal='center', vertical='center')
        # 开学第一天已经单独设置宋体14,其余日期用size16
        if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
            cell.font = Font(size=16)

    
    current_week += 1

# 设置标题行样式
for col in range(1, len(title_row) + 1):
    cell = sheet.cell(row=1, column=col)
    cell.alignment = Alignment(horizontal='center', vertical='center')
    thin_border = Border(
        left=Side(style='thin', color='000000'),
        right=Side(style='thin', color='000000'),
        top=Side(style='thin', color='000000'),
        bottom=Side(style='thin', color='000000')
    )
    cell.border = thin_border
    cell.fill = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid")  # 浅蓝色
    cell.font = Font(size=16)

# 设置行高和列宽
for row in range(1, sheet.max_row + 2):
    sheet.row_dimensions[row].height = 30

# 特别确保最后一行高度为30
sheet.row_dimensions[sheet.max_row].height = 30

for col in range(1, sheet.max_column + 1):
    column_letter = get_column_letter(col)
    sheet.column_dimensions[column_letter].width = 11.5

# 添加标题行
sheet.insert_rows(1)
sheet.merge_cells('A1:H1')
sheet.cell(row=1, column=1).value = title
sheet.cell(row=1, column=1).alignment = Alignment(horizontal='center', vertical='center')
sheet.cell(row=1, column=1).font = Font(size=18, bold=True)
sheet.cell(row=1, column=1).fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid") 

# 保存工作簿
excel_file = path + fr"\00-03 {title}.xlsx"
workbook.save(excel_file)
print(f"校历已生成: {excel_file}")

# ========== 转换为 PDF ==========
def excel_to_pdf(input_excel_path, output_pdf_path):
    try:
        # 启动 Excel 应用程序
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False  # 不显示 Excel 界面
        
        # 打开 Excel 文件
        workbook = excel.Workbooks.Open(input_excel_path)
        
        # 设置打印区域(整个工作表)
        sheet = workbook.ActiveSheet
        sheet.PageSetup.Zoom = False
        sheet.PageSetup.FitToPagesWide = 1  # 适应宽度到 1 页
        sheet.PageSetup.FitToPagesTall = False  # 高度不限制
        
        # 导出为 PDF
        workbook.ExportAsFixedFormat(0, output_pdf_path)  # 0 表示 PDF 格式
        
        # 关闭 Excel
        workbook.Close(False)
        excel.Quit()
        
        print(f"PDF 已生成: {output_pdf_path}")
    except Exception as e:
        print(f"转换失败: {e}")

# 调用转换函数
pdf_file = path + fr"\00-03 {title}.pdf"
excel_to_pdf(excel_file, pdf_file)

time.sleep(2)

五、第一天日期字号缩小

第一个空格里面的汉字被遮挡了

(在上面的代码里面修改了)

六、"日版"和"日月版"合并

我不想每次都修改两个代码,做一个合并版

python 复制代码
'''
校历合并版本(包含"日"版和"日月"版)
模仿制作2027年2月第二学期的校历(标注节假日)3月第一天是年月日,每月第1天是月日,其他都是日
上学期和下学期
星火讯飞、deepseek修订、阿夏
20270201
'''
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
import datetime
import time, os, gc
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.page import PageMargins
import win32com.client  # 用于 Excel 转 PDF
import pythoncom  # 新增,COM多线程初始化
import psutil     # 新增,用于查杀残留excel进程,pip install psutil

path = r'D:\Python最终内容\20270201校历'
os.makedirs(path, exist_ok=True)

# 全局配置
start_date = datetime.date(2027, 2, 22)  # 2月22日是周一
end_date = datetime.date(2027, 6, 30)

m = 0
left_margin_cm = 1.3
right_margin_cm = 1.3
top_margin_cm = 2
bottom_margin_cm = 2
left_margin_inch = left_margin_cm * 0.393701
right_margin_inch = right_margin_cm * 0.393701
top_margin_inch = top_margin_cm * 0.393701
bottom_margin_inch = bottom_margin_cm * 0.393701
thin_border = Border(
    left=Side(style='thin', color='000000'),
    right=Side(style='thin', color='000000'),
    top=Side(style='thin', color='000000'),
    bottom=Side(style='thin', color='000000')
)
title_row = ["周次", "一", "二", "三", "四", "五", "六", "日"]
def build_single_calendar(display_mode):
    """
    单独生成一个校历工作簿(单个工作表)
    :param display_mode: "day"=日版;"md"=月日版
    :return: 工作簿对象、文件名称
    """
    wb = Workbook()
    sheet = wb.active

    # 页边距
    margins = PageMargins(left=left_margin_inch, right=right_margin_inch,
                          top=top_margin_inch, bottom=bottom_margin_inch)
    sheet.page_margins = margins
    sheet.append(title_row)

    # 生成日期列表
    date_list = [title_row]
    for i in range(m):
        date_list.append([''])
    current_day = start_date
    while current_day <= end_date:
        date_list.append([current_day])
        current_day += datetime.timedelta(days=1)

    # ============ 上学期代码完整注释保留(无截断) ============
    # # 上学期(9-1月)
    # # 计算周数和将日期列表写入Excel

    # current_week = 1
    # for i in range(1, len(date_list), 7):
    #     week_dates = date_list[i:i+7]
    #
    #     # 在A列中添加周次
    #     sheet.cell(row=current_week + 1, column=1).value = f"第{current_week}周"
    #     cell = sheet.cell(row=current_week + 1, column=1)
    #     cell.alignment = Alignment(horizontal='center', vertical='center')
    #     cell.font = Font(size=16)
    #     cell.border = thin_border
    #
    #     for j in range(7):
    #         cell = sheet.cell(row=current_week + 1, column=j + 2)
    #         if j < len(week_dates) and week_dates[j]:
    #             date_obj = week_dates[j][0]
    #             if date_obj.year == 2026 and date_obj.month == 9 and date_obj.day == 1:
    #                 cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
    #                 cell.font = Font(name="宋体", size=12)
    #             elif date_obj.day == 1:
    #                 cell.value = f"{date_obj.month}/{date_obj.day}"
    #                 if date_obj.year == 2026 and date_obj.month == 10 and date_obj.day == 1:
    #                     cell.value = f"{date_obj.month}/{date_obj.day}国庆"
    #                 if date_obj.year == 2027 and date_obj.month == 1 and date_obj.day == 1:
    #                     cell.value = f"{date_obj.month}/{date_obj.day}元旦"
    #             else:
    #                 if display_mode == "day":
    #                     cell.value = f"{date_obj.day}"
    #                 else:
    #                     cell.value = f"{date_obj.month}/{date_obj.day}"
    #                 if date_obj.year == 2026 and date_obj.month == 9 and 25 <= date_obj.day <= 27:
    #                     cell.value = f"{date_obj.day}中秋" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}中秋"
    #                 elif date_obj.year == 2026 and date_obj.month == 10 and 1 <= date_obj.day <= 7:
    #                     cell.value = f"{date_obj.day}国庆" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}国庆"
    #                 elif date_obj.year == 2027 and date_obj.month == 1 and 1 <= date_obj.day <= 3:
    #                     cell.value = f"{date_obj.day}元旦" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}元旦"
    #
    #             is_special_date = False
    #             if date_obj.month == 9 and 25 <= date_obj.day <= 27:
    #                 is_special_date = True
    #                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
    #             if date_obj.month == 10 and 1 <= date_obj.day <= 7:
    #                 is_special_date = True
    #                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
    #             if date_obj.month == 1 and 1 <= date_obj.day <= 3:
    #                 is_special_date = True
    #                 cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
    #             if (date_obj.month == 9 and date_obj.day == 20) or (date_obj.month == 10 and date_obj.day == 10):
    #                 is_special_date = True
    #                 if date_obj.month == 9:
    #                     cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")
    #                 elif date_obj.month == 10:
    #                     cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")
    #             if not is_special_date:
    #                 if j >= 5:
    #                     cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
    #                 else:
    #                     if date_obj.month == 9:
    #                         cell.fill = PatternFill(start_color="FFFFCC", end_color="FFFFCC", fill_type="solid")
    #                     elif date_obj.month == 10:
    #                         cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")
    #                     elif date_obj.month == 11:
    #                         cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")
    #                     elif date_obj.month == 12:
    #                         cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
    #                     elif date_obj.month == 1:
    #                         cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")
    #             cell.border = thin_border
    #             cell.alignment = Alignment(horizontal='center', vertical='center')
    #             if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
    #                 cell.font = Font(size=16)
    #     current_week += 1

    # ---------------------- 下学期绘制(无修改) ----------------------

    current_week = 1
    for i in range(1, len(date_list), 7):
        week_dates = date_list[i:i + 7]

        # A列周次
        cell_week = sheet.cell(row=current_week + 1, column=1)
        cell_week.value = f"第{current_week}周"
        cell_week.alignment = Alignment(horizontal='center', vertical='center')
        cell_week.font = Font(size=16)
        cell_week.border = thin_border

        for j in range(7):
            cell = sheet.cell(row=current_week + 1, column=j + 2)

            if j < len(week_dates) and week_dates[j]:
                date_obj = week_dates[j][0]
                # 日期文字规则
                if date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22:
                    cell.value = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
                    cell.font = Font(name="宋体", size=12)
                elif date_obj.day == 1:
                    cell.value = f"{date_obj.month}/{date_obj.day}"
                    if date_obj.year == 2027 and date_obj.month == 5 and date_obj.day == 1:
                        cell.value = f"{date_obj.month}/{date_obj.day}劳动"
                else:
                    if display_mode == "day":
                        cell.value = f"{date_obj.day}"
                    else:
                        cell.value = f"{date_obj.month}/{date_obj.day}"
                    # 节假日文字
                    if date_obj.year == 2027 and date_obj.month == 4 and 3 <= date_obj.day <= 5:
                        cell.value = f"{date_obj.day}清明" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}清明"
                    elif date_obj.year == 2027 and date_obj.month == 5 and 2 <= date_obj.day <= 5:
                        cell.value = f"{date_obj.day}劳动" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}劳动"
                    elif date_obj.year == 2027 and date_obj.month == 6 and date_obj.day == 9:
                        cell.value = f"{date_obj.day}端午" if display_mode=="day" else f"{date_obj.month}/{date_obj.day}端午"
                
                is_special_date = False

                # 放假白底
                if date_obj.month == 4 and 3 <= date_obj.day <= 5:
                    is_special_date = True
                    cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
                if date_obj.month == 5 and 1 <= date_obj.day <= 5:
                    is_special_date = True
                    cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
                if date_obj.month == 6 and date_obj.day == 9:
                    is_special_date = True
                    cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
                # 补班(独立if,不再elif)
                if date_obj.month == 4 and date_obj.day == 25:
                    is_special_date = True
                    cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")
                if date_obj.month == 5 and date_obj.day == 8:
                    is_special_date = True
                    cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
                # 正常工作日底色
                if not is_special_date:
                    if j >= 5:
                        cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
                    else:
                        if date_obj.month == 2:
                            cell.fill = PatternFill(start_color="FFFF96", end_color="FFFF96", fill_type="solid")
                        elif date_obj.month == 3:
                            cell.fill = PatternFill(start_color="FFCCCC", end_color="FFCCCC", fill_type="solid")
                        elif date_obj.month == 4:
                            cell.fill = PatternFill(start_color="CCFFCC", end_color="CCFFCC", fill_type="solid")
                        elif date_obj.month == 5:
                            cell.fill = PatternFill(start_color="CCCCCC", end_color="CCCCCC", fill_type="solid")
                        elif date_obj.month == 6:
                            cell.fill = PatternFill(start_color="FFCC99", end_color="FFCC99", fill_type="solid")
            # 统一样式
            cell.border = thin_border
            cell.alignment = Alignment(horizontal='center', vertical='center')
            if not (date_obj.year == 2027 and date_obj.month == 2 and date_obj.day == 22):
                cell.font = Font(size=16)
          
        current_week += 1

    # 表头样式(周次 一二三四五六日)
    for col in range(1, len(title_row) + 1):
        cell = sheet.cell(row=1, column=col)
        cell.alignment = Alignment(horizontal='center', vertical='center')
        cell.border = thin_border
        cell.fill = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid")
        cell.font = Font(size=16)

    # 行高列宽
    for row in range(1, sheet.max_row + 2):
        sheet.row_dimensions[row].height = 30
    sheet.row_dimensions[sheet.max_row].height = 30
    for col in range(1, sheet.max_column + 1):
        column_letter = get_column_letter(col)
        sheet.column_dimensions[column_letter].width = 11.5

    # 顶部大标题合并单元格
    sheet.insert_rows(1)
    sheet.merge_cells('A1:H1')
    sheet['A1'].alignment = Alignment(horizontal='center', vertical='center')
    sheet['A1'].font = Font(size=18, bold=True)
    sheet['A1'].fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")

    if display_mode == "day":
        title_text = '2026学年第二学期校历"日"版(阿夏20270201)'
        file_name = r"00-03 2026学年第二学期校历_日版(阿夏20270201)"
    else:
        title_text = '2026学年第二学期校历"月日"版(阿夏20270201)'
        file_name = r"00-03 2026学年第二学期校历_月日版(阿夏20270201)"
    sheet['A1'].value = title_text
    return wb, file_name

# 新增:查杀后台残留EXCEL进程
def kill_excel_process():
    for proc in psutil.process_iter(['pid','name']):
        try:
            if proc.info['name'] and proc.info['name'].lower() == "excel.exe":
                proc.kill()
        except:
            continue
        
# ========== 【修复后的PDF导出函数】 重点:finally强制释放COM对象 ==========
def excel_to_pdf(input_excel_path, output_pdf_path):
    max_retry = 2
    for attempt in range(max_retry):
        # 每次尝试前,先杀光所有残留Excel,释放文件锁
        kill_excel_process()
        time.sleep(2)
        
        pythoncom.CoInitialize()
        excel = None
        wb_com = None
        ws = None
        try:
            excel = win32com.client.Dispatch("Excel.Application")
            excel.Visible = False
            excel.DisplayAlerts = False
            wb_com = excel.Workbooks.Open(input_excel_path)
            ws = wb_com.ActiveSheet
            
            ws.PageSetup.Zoom = False
            ws.PageSetup.FitToPagesWide = 1
            ws.PageSetup.FitToPagesTall = False
            
            ws.ExportAsFixedFormat(0, output_pdf_path)
            time.sleep(4)
            
            print(f"PDF已生成:{output_pdf_path}")
            # ✅ 关闭工作簿
            wb_com.Close(SaveChanges=False)
            # ✅ 退出Excel主程序
            excel.Quit()
            # ✅ 非常关键:清空COM对象引用,防止残留进程
            del ws
            del wb_com
            del excel
            gc.collect()
            gc.collect()
            pythoncom.CoUninitialize()
            # 再次查杀兜底
            kill_excel_process()
            time.sleep(1)
            return True
        except pythoncom.com_error as e:
            print(f"【第{attempt+1}次尝试】COM错误: {e}")
            # 异常分支,也要保证关闭
            try:
                if wb_com:
                    wb_com.Close(SaveChanges=False)
            except: pass
            try:
                if excel:
                    excel.Quit()
            except: pass
            del ws, wb_com, excel
            gc.collect()
            gc.collect()
            pythoncom.CoUninitialize()
            kill_excel_process()
            time.sleep(2)
        except Exception as e:
            print(f"【第{attempt+1}次尝试】其他错误: {e}")
            try:
                if wb_com:
                    wb_com.Close(SaveChanges=False)
            except: pass
            try:
                if excel:
                    excel.Quit()
            except: pass
            del ws, wb_com, excel
            gc.collect()
            gc.collect()
            pythoncom.CoUninitialize()
            kill_excel_process()
            time.sleep(2)
    print(f"PDF转换失败: 重试{max_retry}次仍然失败")
    return False



# ===================== 主程序:生成两套独立文件(共4个) =====================
# 1)生成日版Excel并保存
wb_day, name_day = build_single_calendar("day")
excel_day = os.path.join(path, f"{name_day}.xlsx")
wb_day.save(excel_day)
print(f"日版Excel:{excel_day}")
# 2)生成月日版Excel并保存
wb_md, name_md = build_single_calendar("md")
excel_md = os.path.join(path, f"{name_md}.xlsx")
wb_md.save(excel_md)
print(f"月日版Excel:{excel_md}")
# 3)导出两个PDF,中间增加延时,释放COM
# ========== 主程序PDF导出部分 ==========
pdf_day = os.path.join(path, f"{name_day}.pdf")
pdf_md = os.path.join(path, f"{name_md}.pdf")

kill_excel_process()
time.sleep(2)
excel_to_pdf(excel_day, pdf_day)

kill_excel_process()
time.sleep(3)   # 拉长两次任务之间间隔
excel_to_pdf(excel_md, pdf_md)


print("\n==== 全部4个文件生成完成 ====")
print("①日版xlsx")
print("②月日版xlsx")
print("③日版pdf")
print("④月日版pdf")

运行报错,但还是合并了PDF

相关推荐
泡海椒4 小时前
JQuick-Excel 自定义 SPI Provider:用 fullName 扩展 TRANSFORM 函数
驱动开发·excel
开开心心就好5 小时前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
开开心心就好6 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
泡海椒9 小时前
从 XML 到 Excel:JQuick-Excel 代理与解析器如何协作
xml·excel
BD_Marathon10 小时前
PyPDFLoader和MinerU加载pdf文件
pdf
优选资讯14 小时前
Excel 批量打印标签的完整流程
excel
雪宫街道15 小时前
SpringBoot - POI实现Excel 导入与导出
spring boot·后端·excel
ydjs678899-bot1 天前
如何在Java中打印pdf静默打印和打印对话框选择
java·python·pdf
Data-Miner1 天前
数据分析,除了Excel数据透视表,还有什么工具?——2026 专业精选推荐榜
microsoft·数据分析·excel