gaming1990 发表于 2026-3-6 10:06:15

想打印日历,但有些是要钱的,所以我用python...

本帖最后由 gaming1990 于 2026-3-16 17:28 编辑

算是突然想打印日历,在网上搜不到想要的,又想练一下手,所以有以下代码


补上一份说明文档,用deepseek写的说明文档。

农历日历 HTML 生成器说明文档

概述
本脚本根据指定的年份、农历月份天数、农历月份名称以及当年1月1日的农历日期和星期信息,生成一个包含农历日期的全年日历 HTML 文件。生成的日历以表格形式按月展示,每个单元格显示公历日期和对应的农历日期(初一显示月份名称,如“正月”),并包含基本的样式,适合打印或网页展示。

依赖
- Python 3.x
- 无需第三方库

使用方法
1. 根据需要修改脚本开头的几个关键参数(详见“参数说明”)。
2. 运行脚本:`python 脚本名.py`
3. 脚本将在当前目录下生成一个以年份命名的 HTML 文件(例如 `2026年日历.html`),用浏览器打开即可查看日历。

参数说明
以下变量需根据实际年份的农历数据手动设置,因为农历计算复杂,本脚本不包含天文计算。


 变量名 类型 含义 示例(2026年)
`nong_li_ds` list 农历每个月的天数列表。从农历十一月开始,依次列出全年各月的天数(包含闰月)。列表长度通常大于12(因为有闰月),但脚本会截取与公历天数等长的部分。 ``
`nong_li_yue` list 农历月份名称列表,顺序与 `nong_li_ds` 一一对应。 `["十一月","十二月","正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月","正月"]`
`cx`int 偏移量:公历1月1日对应的农历日期在 `nong_li_days` 列表中的索引减1。例如,如果1月1日是农历十一月十二,则 `nong_li_days` 列表中“十一月”对应的第一个“初一”索引为0,而“十二”应位于索引11,因此 `cx = 11`?实际代码中 `nong_li_days` 是从 `cx` 开始截取,所以 `cx` 应等于“公历1月1日对应的农历日期在全年农历列表中的位置”。 假设1月1日是农历十一月十二,那么 `cx = 11`(因为初一为0,十二为11)。
count int 星期偏移量 :公历1月1日是星期几(以周一为0,周二为1,…,周日为6)。例如2026年1月1日是周四,则 `count = 3`。 `3`
`year` int要生成的公历年份,用于判断闰年及显示标题。 `2026`




注意:
        - `nong_li_ds` 和 `nong_li_yue` 必须严格按照农历顺序(通常从十一月开始)且长度一致。
       - `cx` 的值直接影响农历日期对齐,必须精确计算。
       - `count` 确保星期显示正确。
       - 以上参数均需手动查询农历数据后填入,脚本无法自动推算。

脚本逻辑详解
1. 公历天数生成
   根据 `year` 判断闰年,生成每月天数列表 `ping_nian`(平年/闰年各月天数)。

2. 公历日期列表
   通过 `listes_day` 函数将每个月的天数展开为从1开始的连续数字列表 `days`(长度为全年总天数)。

3. 农历日期列表
   使用 `nong_li_ds` 提供的每月天数,通过 `listes_nong_li_day` 展开为农历日期名称列表 `nong_li_days`(例如“初一”、“初二”……)。随后将列表中的每个“初一”替换为对应的农历月份名称(如“正月”),替换时依赖 `count` 变量作为索引——**此处存在潜在问题**,因为 `count` 同时用于星期计数,可能导致月份名称错乱。建议后续版本使用独立计数器。

4. 农历截取对齐
   根据 `cx` 偏移量,从 `nong_li_days` 中截取与公历 `days` 等长的片段,确保农历日期与公历日期一一对应。

5. HTML 生成
   - 构建包含 CSS 样式的 HTML 模板。
   - 遍历 `days` 列表,同时跟踪星期计数器 `count` 和农历索引 `day_i`。
   - 每月第一天开始新的表格,并根据当前星期补足前面的空白单元格。
   - 每天输出一个单元格,包含公历日期和对应的农历日期。
   - 每月最后一天补足行末空白单元格,保证表格完整。
   - 所有月份表格组合成一个完整的 HTML 文件。

6. 文件输出
   将生成的 HTML 字符串写入 `{year}年日历.html`。

输出示例
生成的 HTML 日历具有以下特点:
- 每个月份为一个独立表格,标题为“2026年X月”。
- 表头包含周次(该月第几周)和星期一到星期日。
- 每个日期单元格:
- 上方大号数字为公历日期。
- 下方红色小字为农历日期(初一显示月份,其余显示“廿三”等)。
- 页面顶部有年份导航(未实现实际链接,仅占位)。
- 样式支持打印,打印时隐藏下载按钮等无关元素。

注意事项
- 农历数据的准确性:脚本完全依赖手动设置的 `nong_li_ds`、`nong_li_yue` 和 `cx`,如果数据错误,日历将完全错乱。
- 变量冲突:代码中 `count` 既用于星期计数,又用于替换农历月份时的索引,这可能导致农历月份名称错位。建议使用独立变量(例如 `month_index`)来遍历农历月份。
- 闰月处理:农历月份列表需包含闰月,例如 `nong_li_ds` 中某月为闰四月,则对应 `nong_li_yue` 中应为“闰四月”。脚本不会自动识别“闰”字,需手动在名称中添加。
- 周次显示:表格第一列显示“周X”,X为当前月份内该周是第几周(从1开始),并非当年的周数。
- 空白单元格填充:每月1日前和最后一天后都会填充空白单元格,使每周完整显示7天。

自定义修改
- 如需修改日历样式,可调整 `<style>` 标签内的 CSS。
- 如需添加节气、节日等,可在生成单元格时判断日期并添加相应 `<span>`。

已知问题
- 农历月份名称替换时使用了与星期计数器相同的 `count` 变量,可能导致月份索引错误。建议在替换前备份一个专用计数器。
- 代码未做异常处理,若 `nong_li_ds` 长度不足或 `cx` 超出范围,会引发索引错误。

示例运行
以2026年为例,参数已预设,直接运行脚本即可生成 `2026年日历.html`。建议用浏览器打开查看效果。

#例1;

#农历大小月的天数列表 实时修改
#   11 12 12345678910 11 12 1 多些月份没关系,后面是有可能用到的
nong_li_ds =

#农历月份多一些是因为阳历和农历不一致,并考虑到有闰月
nong_li_yue=["十一月","十二月","正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月","正月"]

#按1月1号的农历号减一
cx = 12

# count 计数周几,1月1号是星期四,周一开始算,所以是第四4天,0,1,2,3
count = 3

#年份
year = 2026

# 以上参数要按实际修改,所有写这个日历的代码是为什么呢……………………。


#阳历的天数
days =[]

#农历的天数
nong_li_days =[]

nong_li = [" ",'初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十',
      '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九','廿十',
      '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十']

# 判断year是平年还是闰年
def is_leap_year(year):
    # 如果年份能被4整除且不能被100整除,或者能被400整除,则是闰年
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
      return True
    else:
      return False
# 闰年的天数要在这里修改      
if is_leap_year(year):
    ping_nian =
else:
    ping_nian =
   
# 新历列表添加项目函数
def listes_day(yue_di):
    for i in range(1,yue_di):
      days.append(i)
      
# 农历列表添加项目函数
def listes_nong_li_day(yue_di):
    for i in range(1,yue_di):
      nong_li_days.append(nong_li)
'''      
def get_days(months):         
    for i in range(len(months)):
      listes_day(months+1)
      
def get_nong_li_days(months):         
    for i in range(len(months)):
      listes_nong_li_day(months+1)
'''
# 按每月的天数添加日子
def get_days_hs(months,hs):
    for i in range(len(months)):
      hs(months+1)
      
get_days_hs(ping_nian,listes_day)
get_days_hs(nong_li_ds,listes_nong_li_day)

#把农历每月的初一改成当月的月份
count1 = 0
for i in range(len(nong_li_days)):
    if nong_li_days == "初一":
      nong_li_days = nong_li_yue
      count1 += 1
      
# 闰年378天,12按1月1号的农历号减一         
nong_li_days = nong_li_days

#print(nong_li_days)
#print(len(nong_li_days))
#print(days)
#print(len(days))

# 这个随便抄的AI的 ,对css不熟。
text = """
<!DOCTYPE html>
<html lang="zh-CN">
<head> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{year}年日历表</title>
<style>body{ font-family: 'Microsoft YaHei', sans-serif; line-height: 1.6; margin: 20px; background-color: #f9f9f9; color: #333; }
.container { max-width: 1200px; margin: 0 auto; background-color: #fff; padding: 30px; border-radius: 10px;box-shadow: 0 2px 15px rgba(0,0,0,0.1); }
h1 { text-align: center; color: #2c3e50; margin-bottom: 10px; border-bottom: 2px solid #3498db; padding-bottom: 15px; }
.subtitle { text-align: center;color: #7f8c8d; margin-bottom: 30px; font-size: 1.1em; }
.year-nav { text-align: center; margin-bottom: 20px; font-size: 1.2em; }
.year-nav a { text-decoration: none; color: #3498db; margin: 0 15px; padding: 5px 10px;border: 1px solid #ddd; border-radius: 4px; }
.year-nav a:hover { background-color: #f0f0f0; }
.month-table { width: 100%; border-collapse: collapse; margin-bottom: 40px; page-break-inside: avoid; }
.month-table caption { caption-side: top; font-size: 1.5em;font-weight: bold; padding: 15px;
                                                background-color: #3498db; color: white; border-radius: 5px 5px 0 0;}
.month-table th, .month-table td { border: 1px solid #ddd; padding: 12px 8px; text-align: center; vertical-align: top; width: 10.28%; }
.month-table th { background-color: #f2f2f2; font-weight: bold; color: #2c3e50; }
.day-cell { min-height: 60px; position: relative; }
.day-num { font-size: 1.2em; font-weight: bold; display: block; margin-bottom: 5px; }
.lunar { font-size: 0.85em; color: #e74c3c; display: block; margin-bottom: 3px; }
.festival, .solar-term { font-size: 0.8em; color: #27ae60; display: block; font-weight: bold; margin-top: 3px; }
.weekend { background-color: #3fcb54; } .rest-day { color: #e74c3c; font-weight: bold; }
.work-day { color: #f39c12; font-weight: bold; }
.download-section { text-align: center; margin-top: 40px;padding-top: 20px; border-top: 1px dashed #ccc; }
.download-btn { display: inline-block; background-color: #2ecc71;color: white; padding: 12px 25px; margin: 10px;
                                text-decoration: none; border-radius: 5px; font-weight: bold; }
.download-btn:hover{ background-color: #27ae60; }
.note { font-size: 0.9em; color: #95a5a6; text-align: center; margin-top: 10px; }
@media print {
        body { background-color: white; margin: 0; padding: 0; }
        .container { box-shadow: none; padding: 0; }
        .download-section, .year-nav { display: none;} }
</style> </head> <body>

"""

#print(nong_li_days)
#print(len(nong_li_days))
#print(days)
#print(len(days))


day_i = 0

for i in days:
    if count % 7 == 0 and i != 1 :# 每月月底多了一个空白周
      text += f'</tr><tr><td >{(count//7)+1}</td>'
    if i == 1:
      text += f"""<table class="month-table">
      <caption>{year}年{(day_i//30)+1}月</caption>
      <thead>
            <tr>
                <th>周</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th><th>日</th>
            </tr>
      </thead><tbody>""" # 每月1号前换行
      text +=f"<tr><td>{(count//7)+1}</td>"
      # 问题:结尾的时候,多了一周显示 如果最后一天是周日
      
      for a in range(count%7):#1号前补空格填满一周
            text +="<td></td>"
            
    text += f'<td class="day-cell"><span class="day-num">{i}</span><span class="lunar">{nong_li_days}</span></td>'# 每日的日
    if i >= 28:
      try:
            if days==1: #月的最后一天补空格填满一周
                for a in range(6-count%7):
                  text +="<td></td>"
      except:#年的最后一天补空格填满一周
            for a in range(6-count%7):
                text +="<td></td>"
    day_i+=1
    count+=1
   
text += """                </tr>       
               
        </tbody>
        </table>

</div>

<script>
    document.addEventListener('DOMContentLoaded', function() {
    });
</script>

</body> </html>"""


#print(text)
#写入文件
filename = f"{year}年日历.html"
#with open("2026.html",'w',encoding='utf-8')as f:
with open(filename,'w',encoding='utf-8')as f:
    f.write(text)



文档版本:1.0
最后更新:2026年3月16日

不二如是 发表于 2026-3-6 19:06:29

建议补个说明文档
页: [1]
查看完整版本: 想打印日历,但有些是要钱的,所以我用python...