Technologie
Van HTML naar PDF: complexe layouts zonder browserengine in je applicatie
PDF-generatie is in de meeste .NET-applicaties geen probleem, zolang het om eenvoudige exports gaat. Maar zodra complexe layouts en visuele opmaak een rol spelen, wordt de aanpak al snel minder vanzelfsprekend.
Tijdens een gesprek met een collega over de beperkingen van PDFSharp, een .NET-bibliotheek waarbij je alles handmatig in code moet 'tekenen', kwam een alternatief ter sprake: PDF's genereren vanuit HTML-templates via een headless browser met Puppeteer. De ontwerpvrijheid spreekt aan. Maar een browserengine en server-side JavaScript integreren in een bestaande .NET-webapplicatie heeft consequenties. Het verzwaart deployments, voegt afhankelijkheden toe en vraagt om regelmatige updates voor veiligheid en compatibiliteit. De vraag was of het ook anders kon.
HTML naar PDF: waarom een losse service logischer is
De verkenning richtte zich op een lichtgewicht, serverloze service die de PDF-logica afzonderlijk afhandelt. Een Azure Function leek een logische keuze.
Online waren de signalen wisselend. Oudere artikelen stelden dat Puppeteer binnen een Azure Function niet werkt. Recentere bronnen suggereerden dat het mogelijk is, met de nodige voorbehouden. Genoeg reden om het van de grond af te testen, met ondersteuning van Claude Code AI.
De opzet: Puppeteer, Chromium en een Azure Function
De opzet bestaat uit een paar losse onderdelen die samen de PDF-generatie mogelijk maken.
- Puppeteer-Core: een JavaScript-bibliotheek om Chrome headless aan te sturen, zonder de volledige Chromium-browser mee te nemen. Die volledige versie is te groot en werkt niet in deze context
- Sparticuz/Chromium: de Linux-build van Chromium voor serverloze platforms. Noodzakelijk om de browserengine zelfstandig op de function te draaien.
- Azure Functions Core Tools: voor het lokaal aanmaken, uitvoeren en testen van de functions.
- Node.js-functiecode: geschreven met Claude Code AI, gebruikmakend van Puppeteer voor de PDF-generatie. Die function accepteert een absolute URL of directe HTML/CSS-invoer, zodat data niet via een URL hoeft te worden blootgesteld.
- Visual Studio Code: via het Azure-tabblad is het lokale functieproject rechtstreeks te deployen naar een bestaande Azure Function.
Azure Function-plan kiezen: Flex of Consumption?
Het nieuwste Linux Azure Functions-plan is Flex, een pay-per-use-model. Binnen de beschikbare tijd bleek de oplossing daar niet werkend te krijgen: bepaalde modules of afhankelijkheden lijken beperkt te zijn. Het standaard Linux Consumption-plan werkte wel, maar dat is een verouderd plan dat op 30 september 2028 wordt uitgefaseerd.
Wat nu? Ofwel een manier vinden om de beperkingen van het Flex-plan te omzeilen, ofwel overstappen naar een containergebaseerde function. Beide opties vragen meer onderzoek. Voor dit experiment volstaat het Consumption-plan.
Wat de PDF-service ondersteunt
De Azure Function retourneert een PDF-bestand als download. Als invoer accepteert de function HTML/CSS met Base64-ondersteuning of een absolute URL. Daarnaast is er ondersteuning voor aangepaste lettertypen en optionele paginanummering.
Hoe de HTML voor de invoer tot stand komt, valt buiten dit artikel. De aanpak hangt af van de situatie: statische templates met placeholders voor dynamische data, een CMS met een renderingengine, of HTML gegenereerd op basis van formulierinvoer. Alle drie zijn gangbare routes en relatief eenvoudig te itereren dankzij snelle visuele feedback.
Serverless PDF-generatie: wat werkt en wat niet
De aanpak houdt PDF-generatie volledig zelfstandig. Updates en deployments blijven daardoor overzichtelijk, zonder dat de hoofdapplicatie extra complexiteit krijgt.
Er zijn wel aandachtspunten. De keuze voor het juiste Azure Function-plan vraagt nader onderzoek. De afhankelijkheid van headless Chromium is een risico op de langere termijn: als die ooit wordt uitgefaseerd, is een vervanger nodig. In een productieomgeving moet de function goed beveiligd zijn en nooit publiek toegankelijk.
Er bestaan betaalde diensten met vergelijkbare functionaliteit. Die vereisen doorgaans dat gevoelige data extern wordt verwerkt en zijn vaak aanzienlijk duurder. Deze aanpak houdt alles onder eigen beheer en is volledig te hosten binnen Europese Azure-infrastructuur.
Meer weten over PDF-generatie vanuit webapplicaties? Neem contact met ons op.
Dit artikel is gebaseerd op een oorspronkelijk Engelstalig artikel dat Vincent eerder op zijn LinkedInpagina publiceerde. De inhoud is vertaald en bewerkt voor deze publicatie. Aan deze vertaling kunnen geen rechten worden ontleend. Tekst: Vincent van Middendorp. Vertaling: Jesper Oskam