Generate PDF version of a Lightning Component using VF Page

Photo by Michał Mancewicz on Unsplash

Here i am presenting you a way where you can easily replicate your lightning component into an Visual Force Page and then make that page render as PDF to give your sales agent to print out the invoice that they generated using a custom build complex lightning component by using a simple button click on details page layout of any object.

But before starting, to make things simple I will be taking an sample LC which has a single table on it because in general invoices are filled with tables giving details of various products related to the sales made.

So let us start with a sample LC that we need to build. Using the general LC bundle we will be making use of 2 files:


<aura:component controller=”DataForTable”
implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >

<aura:attribute name =”recordDetail” type=”sObject” />

<aura:attribute name =”showTable” type=”Boolean” default=”false”/>

<aura:if isTrue=”{!v.showTable}”>
<div class=”slds-page-header__title slds-page-header__name-title slds-p-bottom_medium”>

<b>Lighting Table</b>

<table class=”slds-table slds-no-row-hover “>
<thead class=”slds-border_bottom”>
<tr class=”slds-line-height_reset”>
<th class=”” scope=”col”>
<div class=”slds-truncate” title=”Optional”>Column 1</div>
<th class=”” scope=”col”>
<div class=”slds-truncate” title=”Items”>Column 2</div>
<th class=”” scope=”col”>
<div class=”slds-truncate” title=”QB Item Code”>Column 3</div>

<aura:iteration items=”{!v.tableRecList}” var=”rec”>


<td style=”text-align: right;”>

<td style=”text-align: right;”>
<b>rec.Data2 </b>

<td style=”text-align: right;”>





doInit: function(component, event, helper) {

var action = component.get(“c.initTable”);


recId: component.get(“v.recordId”)


action.setCallback(this, function(response) {
var state = response.getState();
if (state === “SUCCESS”) {

var dataInReturn = response.getReturnValue();

if(dataInReturn.length != 0){




console.log(‘No Data To Show’);




Apex Controller (DataForTable.apx)

public static List<ObjectName> initTable(Id recId)
{// Write Query to fetch the data and return it .
return List<ObjectName>

So here we have created a custom LC with table, now you can replicate the same code using the basic table tags that are used in HTML, something like this,


<apex:page standardController=”<ObjectName>” extensions=”DataDiplayControllerForVF” showHeader=”false” sidebar=”false” renderAs=”PDF”>

<div style=”margin:2rem;”>

<table width=”100%” style=”border: 1px solid black; font-size:12px;”>
<thead width=”100%”>

<th valign=”top” style=”border-bottom: 1px solid #ddd;background-color: #AB1A2D;color: white;”>
Column 1

<th valign=”top” style=”border-bottom: 1px solid #ddd;background-color: #AB1A2D;color: white;”>
Column 2

<th valign=”top” style=”border-bottom: 1px solid #ddd;background-color: #AB1A2D;color: white;”>
Column 3


<apex:repeat value=”{!dataDisplay}” var=”pi” rendered=”{!showData}” >
<td valign=”top” style=”border-bottom: 1px solid #ddd;”>{!pi.Description}
</td><! — use the api name of the field to display it->
<td valign=”top” style=”border-bottom: 1px solid #ddd;”>{!pi.Name}
</td><! — use the api name of the field to display it->
<td valign=”top” style=”border-bottom: 1px solid #ddd;”{!pi.Item_Detail__c}
</td><! — use the api name of the field to display it->


<apex:outputText styleClass=”redAlert” value=”No records to display” rendered=”{!!showData}”/>



Apex Controller (DataDiplayControllerForVF.apx)

global with sharing class DataDisplayControllerForOrder {

public static Decimal dataDisplay {get; set;}
public static Decimal showData {get; set;}

// Constructor Starts

public DataDisplayControllerForOrder(ApexPages.StandardController stdController){



public static void getRecordOfObject(){

Id recId = ApexPages.CurrentPage().getparameters().get(‘id’);

//USE recId in the query.

String dataFromQuery = ‘QUERY STRUCTURE’;

dataDisplay = Database.query(dataFromQuery);

if(dataDisplay.size() != 0){
showData = true;
showData = false;


Now in explanation to the above code, vf page code is pretty straight forward where table is replicated from LC in the same format using HTML table syntax.

Adding to this <aura:iteration> is replicated using <apex:repeat> in the vf page.

The controller for the vf page provides the necessary data using the Database.query method. In VF page the data on the UI is accessed using the API names of the fields of the particular object for which the vf page is created.

Now once we have our VF page in place, lets move to creating another LC to call this VF page behind a button on the Detail Page.

Here is the code for the helper LC which assists in calling the VF page.


<aura:component implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >

<aura:handler name=”init” value=”{!this}” action=”{!c.openActionWindow}”/>
<aura:handler event=”aura:doneRendering” action=”{!c.doneRendering}”/>
Loading …



openActionWindow : function(component, event, helper) {“/apex/PDFGeneratingVF?id=” + component.get(‘v.recordId’), ‘_blank’);
doneRendering: function(component, event, helper) {

Now, as we are done with creating assisting LC, we can now create a button on the desired object and following setting should be kept to make it work:

Action Type : Lightning Component

Lightning Component: // Choose the second LC that we created to show VF (vfCallingLC)

Name: // Choose accordingly

Hit Save.

Drag and drop this button on the page layout and voila, pdf version of your LC is presented in a new tab.

If you face some issue with the code, please feel free to shoot it in comments would try to answer as soon as i can.

Cheers !!!




Software professional who loves to write and share. Have lots of stories and learnings related to life, food, salesforce, blockchain & photography keep reading

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Start a new website with Gatsby Prismic CMS & Netlify

Importing your Up Bank balances to Google Spreadsheet

Functional-Light Programming

Jump Search in JavaScript

[Action required] Your Trial has Expired — Wed Apr 21 2021

Zenity Command option:-

JavaScript Data Structures: Trees (pt. 1)

gif of a tree sprouting

Given an array of characters, compress it in-place. (using char data type)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Shrey Soni

Shrey Soni

Software professional who loves to write and share. Have lots of stories and learnings related to life, food, salesforce, blockchain & photography keep reading

More from Medium

Salesforce Summer ’22 Release Timeline

Fault tolerance for Journey Builder custom activities

Salesforce FSC Rollup-by-Lookup and Bulk Data Load Jobs

Process Automation in Salesforce