====== 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