Python日历.HTMLCalendar

6
我想使用Python内置的日历模块创建带数据的HTML日历。我这么说是因为我可能会考虑到更好的方法,但现在还有些个人问题。我不知道这是否意味着要这样使用,但如果您无法将日期至少转换为,那么它似乎有点无意义。

这将设置本月的日历,以星期日作为第一天。

import calendar
myCal = calendar.HTMLCalendar(calendar.SUNDAY)
print myCal.formatmonth(2009, 7)

它打印出来

<table border="0" cellpadding="0" cellspacing="0" class="month">\n<tr>
<th colspan="7" class="month">July 2009</th></tr>\n<tr><th class="sun">Sun</th>
<th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th>
<th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th></tr>\n
<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td>
<td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td>
<td class="sat">4</td></tr>\n<tr><td class="sun">5</td><td class="mon">6</td><td class="tue">7</td>
<td class="wed">8</td><td class="thu">9</td><td class="fri">10</td>
<td class="sat">11</td></tr>\n<tr><td class="sun">12</td><td class="mon">13</td>
<td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td>
<td class="sat">18</td></tr>\n<tr><td class="sun">19</td><td class="mon">20</td>
<td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td>
<td class="sat">25</td></tr>\n<tr><td class="sun">26</td><td class="mon">27</td>
<td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="fri">31</td>
<td class="noday">&nbsp;</td></tr>\n</table>\n

我希望在HTMLCalendar对象渲染html字符串之前插入一些数据,但我无法弄清楚如何实现。
例如:
<td class="tue">28<br />[my data]</td>

似乎HTMLCalendar对象是不可变的,而且相当无用...虽然日历对象中还有其他有用的东西,但并非HTMLCalendar。真遗憾。 - Kenny Pyatt
2
我认为他们应该移除HTMLCalendar,因为它不是一个HTML库。为什么不使用RTFCalendar或PDDFCalendar呢?日历模块应该生成纯日历,由用户自行渲染。 - Anurag Uniyal
6个回答

45

创建一个继承自HTMLCalendar类的新类。
覆盖formatday方法。

像“这个库没用”这样的评论显然不理解Python。

class EmployeeScheduleCalendar(HTMLCalendar):
    def formatday(self, day, weekday):
        """
          Return a day as a table cell.
        """
        if day == 0:
            return '<td class="noday">&nbsp;</td>' # day outside month
        else:
            return '<td class="%s"><a href="%s">%d</a></td>' % (self.cssclasses[weekday], weekday, day)

2
我看不出有什么你不能用令人惊叹的Python语言和标准日历库完成的事情。+1 - Paxwell
1
当子类化时,一个不错的技巧是使用 super 调用原始函数(如果需要),这样您就不必重新编写原始函数的代码。我制作了一个突出显示某些日期的 HTML 日历... - flutefreak7

16

日历模块在过去通常都没什么用,但是在2.5版本中引入了Calendar对象。虽然它不会为您渲染HTML日历,但它有大量的方法可以帮助您生成一个日历。

例如,monthdatescalendar(year, month)将给您提供一个月中所有周数的列表,其中每个周数又是七天的列表。因此,monthdatescalendar(2009, 7)将以 [[datetime.date(2009, 6, 29), datetime.date(2009, 6, 30), 开始,以 datetime.date(2009, 8, 1), datetime.date(2009, 8, 2)]] 结束。

有了这个,接下来生成所需的HTML变得非常容易。


4
您可以继承HTMLCalendar并覆盖其方法以实现您想要的任何操作,例如: http://journal.uggedal.com/creating-a-flexible-monthly-calendar-in-django/ 如果您参考HTMLCalendar的文档(http://svn.python.org/view/python/branches/release27-maint/Lib/calendar.py?view=markup),您会发现formatday()方法非常简单。只需像上面链接中的示例那样覆盖它,以执行您想要的任何操作。所以HTMLCalendar并不是毫无用处的。;)

让一个旧帖子重生的方法! - Kenny Pyatt

0

不知道你具体想要实现什么,所以很难说,但是我有一个想法。

与其打印myCal.formatmonth(2009, 7),为什么不将其赋值给一个字符串呢。然后你可以用正则表达式来操作它。

这里有一个非常糟糕的示例:

import calendar
import re

myCal = calendar.HTMLCalendar(calendar.SUNDAY)
myStr = myCal.formatmonth(2009, 7)

re.sub('28', '28<br/>[My Data]', myStr)

print myStr

它能够实现你想要的功能,但是它看起来相当丑陋。


1
最终的目标是从MySQL中获取数据并将其插入到日历中。有数十种方法可以做到这一点,我想“嘿,Python自带电池”,所以我寻找了一些可以生成HTML日历的工具。我发现了calendar.HTMLCalendar对象。但它似乎不想让你用任何信息来加载日历。所以,它变得有点私人化了。 - Kenny Pyatt
我添加了一个例子,但这可能是最糟糕的方法。您在这个项目中使用Web框架吗?您的框架可能包括更好的制作日历的方法。 - Anthony Lewis
我在沮丧的时候确实写了类似的东西。 - Kenny Pyatt

0
您可以将看起来有效的html加载到XML树中,修改它,然后再次输出它。例如,这会将<br/> cool添加到每个Tue td节点。
import calendar
import xml.etree.ElementTree as etree

myCal = calendar.HTMLCalendar(calendar.SUNDAY)
htmlStr = myCal.formatmonth(2009, 7)
htmlStr = htmlStr.replace("&nbsp;"," ")

root = etree.fromstring(htmlStr)
for elem in root.findall("*//td"):
    if elem.get("class") != "tue":
        continue
    elem.text += "!"

    br = etree.SubElement(elem, "br")
    br.tail = "cool!"

print etree.tostring(root)

我还不知道你为什么需要生成HTML日历, 但根据你正在使用的需求和框架,有更好的方法来实现它。


2
最终目标是员工排班管理器。我可能不会使用日历模块。我阅读了它的Python源代码,发现它不允许任何修改。它只是打印一个HTML表格。对我来说似乎完全没有用处。你的方法似乎可以行得通。 - Kenny Pyatt
这是一个Web应用程序还是桌面应用程序?如果是桌面应用程序,使用哪个框架?为什么在这种情况下需要HTML?如果是Web应用程序,有更好的HTML日历控件可用。 - Anurag Uniyal
是的,您可以使用我的方法修改日历的HTML输出,这也是您的问题,因此您可以接受这个作为答案 :) - Anurag Uniyal

0
你可以创建一个HTMLCalendar对象,然后使用cssclasses属性分配类,稍后只需使用formatmonth方法创建日历,这是我在Django应用程序中的做法:
from calendar import HTMLCalendar

today = datetime.today()
    month = today.month
    year = today.year
    cal = HTMLCalendar()
    cal.cssclasses = ["mon text-bold", "tue", "wed", "thu", "fri", "sat", "sun red"]
    final_cal = cal.formatmonth(year, month)

这是我的源代码:https://docs.python.org/3/library/calendar.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接