Overview
The PDF Report Generation feature creates professional, downloadable attendance reports containing complete employee check-in history, tardiness tracking, and cumulative statistics. Built with ReportLab, the system generates structured PDF documents that can be printed, archived, or shared with stakeholders.Reports are generated on-demand and include all historical attendance data from the system, not just current day records.
Key Features
Complete History
Every attendance record with username, date, time, and status
Automatic Status Detection
Late arrivals (after 8:30 AM) automatically flagged as “RETARDO”
Statistical Summary
Cumulative tardiness count by employee at end of report
Instant Download
PDF generated in-memory and streamed directly to browser
How to Generate Reports
Direct URL Access
Reports can also be generated directly via URL:Technical Implementation
Backend Route Handler
The complete PDF generation logic inapp.py:184-231:
Report Structure
Page Layout
The PDF uses standard US Letter page size (8.5” x 11”):- Header Section
- Table Headers
- Data Rows
- Summary Section
Position: Top of page (y=750)Includes:
- Report title: “REPORTE DE ASISTENCIA”
- Generation timestamp in format: YYYY-MM-DD HH:MM:SS
- Horizontal separator line
What’s Included
Complete Attendance Records
Every entry fromregistros.json appears in the report:
| Maestro | Fecha | Hora | Estado |
|---|---|---|---|
| empleado1 | 2026-03-05 | 08:45:00 | RETARDO |
| empleado2 | 2026-03-05 | 08:15:00 | PUNTUAL |
GPS coordinates (lat/lon) are not included in the PDF report. Only username, date, time, and status appear.
Tardiness Detection
The same 8:30 AM threshold used in the Admin Dashboard:PUNTUAL
Check-in at or before 08:30:00
RETARDO
Check-in after 08:30:00 (late arrival)
Statistical Summary
The report concludes with cumulative tardiness by employee:Employees with zero tardiness do not appear in the summary section.
Pagination
Automatic Page Breaks
The system prevents content from running off the page:- Page Capacity
- Multi-Page Reports
Approximate records per page: 40-45 entriesCalculation:
- Starting y: 685 (after headers)
- Ending y: 80 (bottom margin)
- Row height: 15 points
- Capacity: (685 - 80) / 15 ≈ 40 rows
Download Behavior
In-Memory Generation
The PDF is generated entirely in memory without creating temporary files:- No disk I/O overhead
- No cleanup required
- Thread-safe for concurrent requests
- Works in containerized environments without persistent storage
File Download
Flask’ssend_file() streams the PDF to the browser:
as_attachment=True
Browser downloads the file instead of opening in a new tab
download_name
Sets default filename in download dialog (user can rename)
mimetype
Tells browser this is a PDF document for proper handling
buffer
In-memory BytesIO object streamed directly to response
Use Cases
- Daily Records
- Payroll Integration
- Performance Reviews
- Compliance Audits
Scenario: End-of-day attendance archivingWorkflow:
- Admin reviews dashboard at 5 PM
- Generates PDF report
- Saves to network drive or prints for physical filing
- Shares via email with HR department
Customization Examples
Add Page Numbers
Add Company Logo
Color-Coded Status
Filter by Date Range
Add GPS Coordinates
Performance Considerations
Large datasets
Large datasets
Challenge: Reports with thousands of recordsImpact:
- Generation time increases (5-10 seconds for 1000+ records)
- Memory usage grows (10-20 MB in memory)
- Browser may show “file downloading” for longer
- Add date range filters to limit records
- Implement pagination (separate reports by month)
- Consider switching to Excel format for very large exports
- Add loading indicator on admin dashboard
Concurrent requests
Concurrent requests
Scenario: Multiple admins generating reports simultaneouslyBehavior:
- Each request creates independent BytesIO buffer
- No shared state between requests
- Thread-safe by design
- High memory usage if many concurrent reports
- CPU spikes during ReportLab rendering
- Implement rate limiting on
/reporte-pdfendpoint - Cache recently generated reports (5-minute TTL)
- Use background task queue for report generation
Error Handling
Missing Data Fields
The code uses.get() with fallback values:
Malformed records will appear in the PDF with placeholder values instead of causing errors.
Empty Records File
Ifregistros.json is empty or missing:
- Header and table columns
- No data rows
- Empty summary section
- Message: “No records found” can be added
Integration with Other Features
The PDF reporting system leverages data from:- Employee Tracking: All GPS check-ins form the report dataset
- Admin Dashboard: One-click access via ”📥 Reporte PDF” button
- Automated Reminders: Tardiness detection uses same 8:30 AM logic
Best Practices
Troubleshooting
PDF downloads but won't open
PDF downloads but won't open
Symptoms: File downloads successfully but shows “corrupted” error in PDF readerPossible causes:
p.save()not called beforebuffer.seek(0)- Exception occurred during generation (partial write)
- ReportLab not installed or outdated
- Check server logs for Python exceptions
- Verify ReportLab version:
pip show reportlab - Test PDF generation in Python shell
- Ensure
buffer.seek(0)is called beforesend_file()
Report generation is slow
Report generation is slow
Symptoms: Long delay before download startsPossible causes:
- Thousands of attendance records
- Multiple page breaks and pagination
- Slow disk I/O when reading
registros.json
- Add date filters to limit records
- Optimize JSON file reading (consider database migration)
- Implement caching for recently generated reports
- Add loading spinner on frontend
Missing records in report
Missing records in report
Symptoms: Dashboard shows more records than appear in PDFPossible causes:
registros.jsonnot synchronized (cached old version)- Records added after PDF generation started
- Pagination bug causing data loss
- Refresh dashboard before generating report
- Check file modification timestamp of
registros.json - Review pagination logic for off-by-one errors
- Add record count verification in PDF footer
Future Enhancements
Date Range Filters
Allow admins to specify start/end dates for custom report periods
Excel Export
Alternative format with formulas, pivot tables, and charts
Email Delivery
Automatically email reports to stakeholders on schedule
Visual Charts
Embed Chart.js graphs directly in PDF (requires additional library)