====== Python 使用reportlab 创建PDF格式日历 ======
使用到的模块有:
* calendar (python self contained)
* reportlab
===== 功能修改 =====
做了下面的一些修改。
==== 字体 ====
在源代码里面增加了字体部分:
canvas.setFont("Times-Roman", 20)
==== 增加日历的星期名称 ====
weekheader = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
日历表格中行数增加一行,表格的线也都补齐了。
生成的日历PDF文件为: {{ :python-files: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 =====
* https://billmill.org/static/files/pdf_calendar.py [[python-files:pdf-calendar-orignal-ref-back]]
* http://stackoverflow.com/questions/7276017/producing-a-printable-calendar-with-python