Generate a Monthly Calendar PDF in Python
Create a Python utility that generates a monthly calendar PDF using ReportLab, with weekday headers and day numbers laid out in a grid.
pip install reportlab
Python code
41 linesfrom calendar import TextCalendar
from datetime import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import os
def generate_monthly_calendar_pdf(year, month, filename="calendar.pdf"):
cal = TextCalendar()
days = cal.monthdays2calendar(year, month)
month_name = datetime(year, month, 1).strftime("%B %Y")
c = canvas.Canvas(filename, pagesize=letter)
width, height = letter
c.setFont("Helvetica-Bold", 24)
c.drawCentredString(width / 2, height - 60, month_name)
cell_width = (width - 40) / 7
cell_height = 30
start_y = height - 100
days_header = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
for i, day in enumerate(days_header):
x = 20 + i * cell_width
c.setFont("Helvetica-Bold", 10)
c.drawString(x + 5, start_y + 5, day)
for row_idx, week in enumerate(days):
y = start_y - (row_idx + 1) * (cell_height + 5)
for col_idx, (day_num, _) in enumerate(week):
if day_num != 0:
x = 20 + col_idx * cell_width
c.setFont("Helvetica", 9)
c.drawString(x + 3, y + 3, str(day_num))
c.save()
return os.path.abspath(filename)
if __name__ == "__main__":
path = generate_monthly_calendar_pdf(2025, 3, "march_2025.pdf")
print(f"Calendar PDF saved to: {path}")
Output
Calendar PDF saved to: /full/path/to/march_2025.pdf
How it works
The code uses TextCalendar.monthdays2calendar to get the day numbers and their weekday positions for each week of the month. ReportLab's canvas.Canvas draws the title, weekday headers, and day numbers at calculated coordinates. The grid layout divides the page width by 7 to compute equal cell widths. Saving the canvas produces a PDF file at the specified path.
Common mistakes
- Forgetting to install reportlab via pip before running the script
- Using monthdayscalendar instead of monthdays2calendar, which omits weekday info
- Not adjusting fonts or cell sizes for months with 5 or 6 weeks, causing overflow
- Hardcoding paths without os.path.abspath for cross-platform compatibility
Variations
- Use `from calendar import HTMLCalendar` to generate an HTML calendar instead
- Add event annotations by modifying the draw loop to include text underneath day numbers
Real-world use cases
- Distributing printable shift schedules or appointment calendars to team members
- Creating branded monthly planners for marketing or sales content
- Generating date-stamped worksheets or activity logs for classroom use
Sponsored
More from Files & data
- Audit File Permissions Across a Project in Python easy
- Automatically Detect Corrupted Files Using SHA-256 Checksums in Python easy
- Automatically Highlight Data Validation Errors Inside Excel Files in Python easy
- Build a Command-Line To-Do List Application with Data Persistence in Python easy
- Build a Personal Work Hours Tracker in Python medium
- Build a Python Script That Detects and Deletes Empty Files Across Folders easy
Keep learning
Related tutorials and quizzes for this topic.