If xhtml2pdf fails to install on Flatlogic's server (missing C libraries), the top-level import crashed the entire WSGI app. Now it imports lazily inside render_to_pdf() so the app starts even without xhtml2pdf — only PDF generation degrades gracefully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
# === PDF GENERATION ===
|
|
# Converts a Django HTML template into a PDF file using xhtml2pdf.
|
|
# Used for payslip and receipt PDF attachments sent via email.
|
|
#
|
|
# IMPORTANT: xhtml2pdf is imported LAZILY (inside the function, not at the
|
|
# top of the file). This is intentional — if xhtml2pdf fails to install on
|
|
# the server (missing C libraries), the rest of the app still works.
|
|
# Only PDF generation will fail gracefully.
|
|
|
|
import logging
|
|
from io import BytesIO
|
|
from django.template.loader import get_template
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def render_to_pdf(template_src, context_dict=None):
|
|
"""
|
|
Render a Django template to PDF bytes.
|
|
|
|
Args:
|
|
template_src: Path to the template (e.g. 'core/pdf/payslip_pdf.html')
|
|
context_dict: Template context variables
|
|
|
|
Returns:
|
|
PDF content as bytes, or None if there was an error.
|
|
"""
|
|
if context_dict is None:
|
|
context_dict = {}
|
|
|
|
# --- Lazy import: only load xhtml2pdf when actually generating a PDF ---
|
|
# This prevents the entire app from crashing if xhtml2pdf isn't installed.
|
|
try:
|
|
from xhtml2pdf import pisa
|
|
except ImportError:
|
|
logger.error(
|
|
"xhtml2pdf is not installed — cannot generate PDF. "
|
|
"Install it with: pip install xhtml2pdf"
|
|
)
|
|
return None
|
|
|
|
# Load and render the HTML template
|
|
template = get_template(template_src)
|
|
html = template.render(context_dict)
|
|
|
|
# Convert HTML to PDF
|
|
result = BytesIO()
|
|
pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result)
|
|
|
|
if not pdf.err:
|
|
return result.getvalue()
|
|
return None
|