LWC PDF Generation Examples

Scenario

Generate a PDF from Salesforce record data and store it in Files, with reliable error handling and user feedback.

Example 1: LWC Trigger + Busy State

<template>
    <lightning-button
        label="Generate PDF"
        variant="brand"
        onclick={handleGeneratePdf}
        disabled={isRunning}>
    </lightning-button>
</template>
import { LightningElement, api } from 'lwc';
import generatePdf from '@salesforce/apex/PdfService.generatePdf';

export default class PdfGenerator extends LightningElement {
    @api recordId;
    isRunning = false;

    async handleGeneratePdf() {
        this.isRunning = true;
        try {
            await generatePdf({ recordId: this.recordId });
        } finally {
            this.isRunning = false;
        }
    }
}

Example 2: Apex Service + Named Credential

public with sharing class PdfService {
    @AuraEnabled
    public static Id generatePdf(Id recordId) {
        Account a = [SELECT Id, Name, Industry FROM Account WHERE Id = :recordId LIMIT 1];

        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:PdfRenderer/v1/render');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setTimeout(120000);
        req.setBody(JSON.serialize(new Map<String, Object>{
            'template' => 'account-summary',
            'payload' => new Map<String, Object>{
                'name' => a.Name,
                'industry' => a.Industry
            }
        }));

        HttpResponse res = new Http().send(req);
        if (res.getStatusCode() != 200) {
            throw new CalloutException('PDF render failed: ' + res.getStatusCode());
        }

        ContentVersion cv = new ContentVersion(
            Title = 'Account Summary - ' + a.Name,
            PathOnClient = 'account-summary.pdf',
            VersionData = res.getBodyAsBlob()
        );
        insert cv;
        return cv.Id;
    }
}

Example 3: Test with HttpCalloutMock

@IsTest
private class PdfServiceTest {
    private class PdfMock implements HttpCalloutMock {
        public HttpResponse respond(HttpRequest req) {
            HttpResponse res = new HttpResponse();
            res.setStatusCode(200);
            res.setBodyAsBlob(Blob.valueOf('fake-pdf-content'));
            return res;
        }
    }

    @IsTest
    static void generatePdf_createsFile() {
        Test.setMock(HttpCalloutMock.class, new PdfMock());
        Account a = new Account(Name = 'Acme');
        insert a;

        Test.startTest();
        Id fileId = PdfService.generatePdf(a.Id);
        Test.stopTest();

        System.assertNotEquals(null, fileId);
    }
}

Operational Notes