Wednesday, October 12, 2022

PDF Generation in Lightning Web Component (LWC) Salesforce

Hello Guys in this post I'll explain you how to generate PDF using LWC.

So to achieve this I am creating one LWC and putting that LWC on the Contact Record Detail page, In LWC I'm showing some contacts fields using the HTML file of LWC. Please make sure you're not using any slds class for styling because those classes wont create any styling in PDF. You have to use normal CSS for styling. In LWC, I have one button and on the click of that button PDF. would generate. I also need one Visualforce Page that will be used to render the PDF.

Check below example with Code

Lightning Web Component Code

pdfGenerationLWC.html

<template>
    <div class="container" style="background: white; margin: 1px; border:1px solid black;">
        <h1>Contact Detail</h1>
        <div style="margin-bottom: 10px;">
            Title : {contact.Title}            
        </div>
        <div style="margin-bottom: 10px;">
            <div>Phone : {contact.Phone}</div>
        </div> 
        <div style="margin-bottom: 10px;">
            Name : {contact.FirstName} {contact.LastName}
        </div>
        <div style="margin-bottom: 10px;">
            <div>Home Phone: {contact.HomePhone}</div>  
        </div>                       
    </div>
    <lightning-button variant="brand" label="Download PDF" onclick={downloadPDF}></lightning-button>
</template>

In JS part of LWC I have created one public property recordId, that will receive contact Id and using this Id I'm making a server call to fetch the contact details, also there is one method downloadPDF that will be called on the click of the button and in that first I am getting all html code using queryselector and passing as string to the visulforce page and visualforce page will show all the html code as pdf

pdfGenerationLWC.js

import { LightningElement, api } from 'lwc';
import getContact from '@salesforce/apex/PDFGenerationLWCController.getContact';

export default class PdfGenerationLWC extends LightningElement {
    @api recordId;
    contact = {}
    connectedCallback(){
       getContact({
           recordId : this.recordId
       })
       .then(result=>{
            this.contact = result;
       })
       .catch(error=>{
           console.error(error);
       })
   }
    downloadPDF(){
        let htmlContent = this.template.querySelector('.container')    
        window.location = "/apex/PDFGenerationPage?pdfHTML="+htmlContent.outerHTML;  
    }
}
pdfGenerationLWC.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

Apex controller to fetch the contact details


public with sharing class PDFGenerationLWCController {
    @AuraEnabled
    public static Contact getContact(String recordId){
        try {
            return [SELECT Title, FirstName, LastName, Phone, Owner.FirstName, HomePhone FROM CONTACT WHERE Id=:recordId];
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
    }    
}

Visualforce page

<apex:page controller="pdfPageController" renderAs="pdf" applyHtmlTag="false" showHeader="false" cache="true" readOnly="true">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
            <style>
                @page {
                    size: a4 portrait;    
                    padding-left: 2px;    
                    padding-right: 2px;
                }            
            </style>
        </head>
        <apex:outputText value="{!pdfHTML}" escape="false"/>
    </html>

</apex:page>
Visualforce Page Controller

public with sharing class PDFPageController {
    public String pdfHTML{get;set;}
    public pdfPageController() {
        pdfHTML = ApexPages.currentPage().getParameters().get('pdfHTML');
    }
}

Output Screen shots

If you guys have any question, please comment below. I'll be happy to help.