鱼C论坛

 找回密码
 立即注册
查看: 97|回复: 1

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

[复制链接]
发表于 2026-3-6 10:06:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 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(因为有闰月),但脚本会截取与公历天数等长的部分。   `[30,29,30,29,30,29,29,30,29,29,30,30,30,29,30]`
`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. #例1;

  2. #农历大小月的天数列表 实时修改
  3. #     11 12 1  2  3  4  5  6  7  8  9  10 11 12 1 多些月份没关系,后面是有可能用到的
  4. nong_li_ds = [30,29,30,29,30,29,29,30,29,29,30,30,30,29,30]

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

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

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

  11. #年份
  12. year = 2026

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


  14. #阳历的天数
  15. days =[]

  16. #农历的天数
  17. nong_li_days =[]

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

  21. # 判断year是平年还是闰年
  22. def is_leap_year(year):
  23.     # 如果年份能被4整除且不能被100整除,或者能被400整除,则是闰年
  24.     if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
  25.         return True
  26.     else:
  27.         return False
  28. # 闰年的天数要在这里修改        
  29. if is_leap_year(year):
  30.     ping_nian = [31,29,31,30,31,30,31,31,30,31,30,31]
  31. else:
  32.     ping_nian = [31,28,31,30,31,30,31,31,30,31,30,31]
  33.    
  34. # 新历列表添加项目函数
  35. def listes_day(yue_di):
  36.     for i in range(1,yue_di):
  37.         days.append(i)
  38.         
  39. # 农历列表添加项目函数
  40. def listes_nong_li_day(yue_di):
  41.     for i in range(1,yue_di):
  42.         nong_li_days.append(nong_li[i])
  43. '''      
  44. def get_days(months):           
  45.     for i in range(len(months)):
  46.         listes_day(months[i]+1)
  47.         
  48. def get_nong_li_days(months):           
  49.     for i in range(len(months)):
  50.         listes_nong_li_day(months[i]+1)
  51. '''
  52. # 按每月的天数添加日子
  53. def get_days_hs(months,hs):
  54.     for i in range(len(months)):
  55.         hs(months[i]+1)
  56.         
  57. get_days_hs(ping_nian,listes_day)
  58. get_days_hs(nong_li_ds,listes_nong_li_day)

  59. #把农历每月的初一改成当月的月份
  60. count1 = 0
  61. for i in range(len(nong_li_days)):
  62.     if nong_li_days[i] == "初一":
  63.         nong_li_days[i] = nong_li_yue[count]
  64.         count1 += 1
  65.         
  66. # 闰年378天,12按1月1号的农历号减一           
  67. nong_li_days = nong_li_days[cx:cx+len(days)]

  68. #print(nong_li_days)
  69. #print(len(nong_li_days))
  70. #print(days)
  71. #print(len(days))

  72. # 这个随便抄的AI的 ,对css不熟。
  73. text = """
  74. <!DOCTYPE html>
  75. <html lang="zh-CN">
  76. <head> <meta charset="UTF-8">
  77. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  78. <title>{year}年日历表</title>
  79. <style>body{ font-family: 'Microsoft YaHei', sans-serif; line-height: 1.6; margin: 20px; background-color: #f9f9f9; color: #333; }
  80. .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); }
  81. h1 { text-align: center; color: #2c3e50; margin-bottom: 10px; border-bottom: 2px solid #3498db; padding-bottom: 15px; }
  82. .subtitle { text-align: center;color: #7f8c8d; margin-bottom: 30px; font-size: 1.1em; }
  83. .year-nav { text-align: center; margin-bottom: 20px; font-size: 1.2em; }
  84. .year-nav a { text-decoration: none; color: #3498db; margin: 0 15px; padding: 5px 10px;border: 1px solid #ddd; border-radius: 4px; }
  85. .year-nav a:hover { background-color: #f0f0f0; }
  86. .month-table { width: 100%; border-collapse: collapse; margin-bottom: 40px; page-break-inside: avoid; }
  87. .month-table caption { caption-side: top; font-size: 1.5em;font-weight: bold; padding: 15px;
  88.                                                 background-color: #3498db; color: white; border-radius: 5px 5px 0 0;}
  89. .month-table th, .month-table td { border: 1px solid #ddd; padding: 12px 8px; text-align: center; vertical-align: top; width: 10.28%; }
  90. .month-table th { background-color: #f2f2f2; font-weight: bold; color: #2c3e50; }
  91. .day-cell { min-height: 60px; position: relative; }
  92. .day-num { font-size: 1.2em; font-weight: bold; display: block; margin-bottom: 5px; }
  93. .lunar { font-size: 0.85em; color: #e74c3c; display: block; margin-bottom: 3px; }
  94. .festival, .solar-term { font-size: 0.8em; color: #27ae60; display: block; font-weight: bold; margin-top: 3px; }
  95. .weekend { background-color: #3fcb54; } .rest-day { color: #e74c3c; font-weight: bold; }
  96. .work-day { color: #f39c12; font-weight: bold; }
  97. .download-section { text-align: center; margin-top: 40px;padding-top: 20px; border-top: 1px dashed #ccc; }
  98. .download-btn { display: inline-block; background-color: #2ecc71;color: white; padding: 12px 25px; margin: 10px;
  99.                                 text-decoration: none; border-radius: 5px; font-weight: bold; }
  100. .download-btn:hover{ background-color: #27ae60; }
  101. .note { font-size: 0.9em; color: #95a5a6; text-align: center; margin-top: 10px; }
  102. @media print {
  103.         body { background-color: white; margin: 0; padding: 0; }
  104.         .container { box-shadow: none; padding: 0; }
  105.         .download-section, .year-nav { display: none;} }
  106. </style> </head> <body>

  107. """

  108. #print(nong_li_days)
  109. #print(len(nong_li_days))
  110. #print(days)
  111. #print(len(days))


  112. day_i = 0

  113. for i in days:
  114.     if count % 7 == 0 and i != 1 :# 每月月底多了一个空白周
  115.         text += f'</tr><tr><td >{(count//7)+1}</td>'
  116.     if i == 1:
  117.         text += f"""<table class="month-table">
  118.         <caption>{year}年{(day_i//30)+1}月</caption>
  119.         <thead>
  120.             <tr>
  121.                 <th>周</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th><th>日</th>
  122.             </tr>
  123.         </thead><tbody>""" # 每月1号前换行
  124.         text +=f"<tr><td>{(count//7)+1}</td>"
  125.         # 问题:结尾的时候,多了一周显示 如果最后一天是周日
  126.         
  127.         for a in range(count%7):#1号前补空格填满一周
  128.             text +="<td></td>"
  129.             
  130.     text += f'<td class="day-cell"><span class="day-num">{i}</span><span class="lunar">{nong_li_days[day_i]}</span></td>'  # 每日的日
  131.     if i >= 28:
  132.         try:
  133.             if days[day_i+1]==1: #月的最后一天补空格填满一周
  134.                 for a in range(6-count%7):
  135.                     text +="<td></td>"
  136.         except:#年的最后一天补空格填满一周
  137.             for a in range(6-count%7):
  138.                 text +="<td></td>"
  139.     day_i+=1
  140.     count+=1
  141.    
  142. text += """                </tr>       
  143.                
  144.         </tbody>
  145.         </table>

  146. </div>

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

  151. </body> </html>"""


  152. #print(text)
  153. #写入文件
  154. filename = f"{year}年日历.html"
  155. #with open("2026.html",'w',encoding='utf-8')as f:
  156. with open(filename,'w',encoding='utf-8')as f:
  157.     f.write(text)
复制代码



文档版本:1.0  
最后更新:2026年3月16日
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-3-6 19:06:29 | 显示全部楼层
建议补个说明文档
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-4-1 15:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表