A local web app for a small room-rental business in Austria: guest register, room ledger, occupancy plan, invoices, the monthly tourist-tax report and the quarterly VAT list. Application code only; it ships no data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
26 lines
1.1 KiB
Python
26 lines
1.1 KiB
Python
"""Render invoice HTML to PDF with a headless Chromium-family browser through Playwright.
|
|
|
|
PDF_BROWSER picks the browser: an installed `msedge` (default) or `chrome`, or `chromium` — Playwright's own
|
|
build, after `playwright install chromium`."""
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
from app import config
|
|
|
|
BROWSER = config.get("PDF_BROWSER", "msedge")
|
|
|
|
|
|
def render(html):
|
|
"""The A4 PDF of a full-bleed HTML page, as bytes."""
|
|
with sync_playwright() as p:
|
|
browser = p.chromium.launch(channel=BROWSER)
|
|
try:
|
|
page = browser.new_page()
|
|
page.set_content(html, wait_until="load")
|
|
# Full-bleed: the template's @page/.sheet own every margin, so the sheet maps 1:1 to the A4 page
|
|
# and the address can be placed by physical millimetres (window-envelope position). Any margin
|
|
# here would re-inset (and scale) the 210mm sheet and throw those millimetres off.
|
|
return page.pdf(format="A4", print_background=True, prefer_css_page_size=True,
|
|
margin={"top": "0", "bottom": "0", "left": "0", "right": "0"})
|
|
finally:
|
|
browser.close()
|