目录

Python 使用reportlab 创建PDF格式日历

使用到的模块有:

功能修改

做了下面的一些修改。

字体

在源代码里面增加了字体部分:

canvas.setFont("Times-Roman", 20)

增加日历的星期名称

weekheader = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];

日历表格中行数增加一行,表格的线也都补齐了。

生成的日历PDF文件为: python-generate-printable-calendar.pdf

Python 源代码

from reportlab.lib import pagesizes
from reportlab.pdfgen.canvas import Canvas
import calendar, time, datetime
from math import floor
 
NOW = datetime.datetime.now()
SIZE = pagesizes.landscape(pagesizes.letter)
 
class NoCanvasError(Exception): pass
 
def nonzero(row):
    return len([x for x in row if x!=0])
 
def createCalendar(month, year=NOW.year, canvas=None, filename=None, \
                   size=SIZE):
    """
    Create a one-month pdf calendar, and return the canvas
 
    month: can be an integer (1=Jan, 12=Dec) or a month abbreviation (Jan, Feb,
            etc.
    year: year in which month falls. Defaults to current year.
    canvas: you may pass in a canvas to add a calendar page to the end.
    filename: String containing the file to write the calendar to
    size: size, in points of the canvas to write on
    """
    weekheader = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
    if type(month) == type(''):
        month = time.strptime(month, "%b")[1]
    if canvas is None and filename is not None:
        canvas = Canvas(filename, size)
    elif canvas is None and filename is None:
        raise NoCanvasError
    monthname = time.strftime("%B", time.strptime(str(month), "%m"))
    calendar.setfirstweekday(calendar.SUNDAY)
    cal = calendar.monthcalendar(year, month)
 
    width, height = size
 
    #draw the month title
    title = monthname + ' ' + str(year)
    canvas.setFont("Helvetica-Bold", 35)
    canvas.drawCentredString(width / 2, height - 40, title)
    height = height - 50
 
 
    #margins
    wmar, hmar = width/45, height/45
 
    #set up constants
    width, height = width - (2*wmar), height - (2*hmar)
    rows, cols = len(cal) + 1, 7  ;# with header
    lastweek = nonzero(cal[-1])
    firstweek = nonzero(cal[0])
    weeks = len(cal)
    rowheight = floor(height / rows)
    boxwidth = floor(width/7)
 
    for row in range(0, rows+1):
        y = hmar + (row * rowheight)
        canvas.line(wmar, y, wmar + (boxwidth * 7), y)
 
    for col in range(8):
        #1 = don't draw line to first or last; 0 = do draw
        last, first = 1, 1
        x = wmar + (col * boxwidth)
        endy = hmar + (rows * rowheight)
        canvas.line(x, hmar, x, endy)
 
    #now fill in the week day abbr
    canvas.setFont("Helvetica-Bold", 25)
    x = wmar + floor(boxwidth/2)
    y = hmar + (rows * rowheight) - floor(rowheight/2) 
    for abbr in weekheader:
      canvas.drawCentredString(x, y, str(abbr))
      x += boxwidth
 
    #now fill in the day numbers and any data
    canvas.setFont("Times-Roman", 20)
    x = wmar + 6
    y = hmar + ((rows -1) * rowheight) - 25 ;# row - 1, represent week header
    for week in cal:
        for day in week:
            if day:
                canvas.drawString(x, y, str(day))
            x = x + boxwidth
        y = y - rowheight
        x = wmar + 6
 
    #finish this page
    canvas.showPage()
 
    return canvas
 
if __name__ == "__main__":
    #create a December, 2005 PDF
    c = createCalendar(4, 2017, filename="python-generate-printable-calendar.pdf")
    #now add January, 2006 to the end
    createCalendar(5, 2017, canvas=c)
    c.save()

Reference