Richard Jones' Log: Year planner PDF generation in Python

Sun, 09 Jan 2005

Rachel and I are trying to introduce some more planning into our lives. To this end, I looked around for some free year planning calendar, but to no avail. So, an hour of hacking later, here's some code (rlcal.py) that generates a couple of PDFs (Jan-Jun, Jul-Dec)

# rlcal.py v1.1 (C) 2005 Richard Jones
# Generates 2 PDF pages for a "year planner". Year is hard-coded.
# license: http://creativecommons.org/licenses/by-nc-sa/2.0
# Requires ReportLab PDF library <http://www.reportlab.org/>
import calendar
from reportlab.lib import colors
from reportlab.graphics import shapes, renderPDF

YEAR = 2005

def half_year(startmon):
    '''"startmon" gives the 1-indexed month to start the page on'''
    mons = []
    reqd = 0
    # ask calendar.py to figure the actual days for each month
    for mon in range(6):
        weeks = calendar.monthcalendar(YEAR, mon + startmon)
        weeks[-1] = filter(None, weeks[-1])
        mdays = []
        for week in weeks:
            mdays.extend(week)
        reqd = max(reqd, len(mdays))
        mons.append(mdays)

    LEFTMARGIN = 5
    DAYCOLWIDTH = 50
    CELLWIDTH  = 80
    CELLHEIGHT = 19
    TOPROWHEIGHT = 18
    WIDTH = LEFTMARGIN + DAYCOLWIDTH + CELLWIDTH*6
    HEIGHT = reqd * CELLHEIGHT + TOPROWHEIGHT

    d = shapes.Drawing(WIDTH, HEIGHT)

    # month headings
    for i in range(6):
        x = LEFTMARGIN + i*CELLWIDTH + DAYCOLWIDTH + CELLWIDTH/2
        d.add(shapes.String(x, HEIGHT-14, calendar.month_abbr[i + startmon],
            fontSize=14, fontName='Times-Bold', textAnchor='middle'))

    # day row headings
    for i in range(reqd):
        y = HEIGHT - i*CELLHEIGHT - TOPROWHEIGHT
        d.add(shapes.String(LEFTMARGIN + 10, y-14, calendar.day_abbr[i%7],
            fontSize=14))

    # cells for each day, light grey background if weekend
    lightgrey = colors.HexColor(0xD0D0D0)
    for j in range(6):
        x = LEFTMARGIN + j*CELLWIDTH + DAYCOLWIDTH
        for i in range(reqd):
            if i >= len(mons[j]) or not mons[j][i]: continue
            y = HEIGHT - i*CELLHEIGHT - TOPROWHEIGHT
            color = (i%7 > 4) and lightgrey or colors.white
            d.add(shapes.Rect(x, y, CELLWIDTH, -CELLHEIGHT, fillColor=color))
            d.add(shapes.String(x+1, y-10, str(mons[j][i]), fontSize=10))
    return d

if __name__ == '__main__':
    renderPDF.drawToFile(half_year(1), 'calendar.jan-jun.pdf')
    renderPDF.drawToFile(half_year(7), 'calendar.jul-dec.pdf')
Comment by Jon on Fri, 31 Aug 2007

Hi,

Just wondering if you have the generated files for next year (2008) - if it's possible would you be able to send a copy over?

Thanks so much!
Jon