3

I have a Lightning component which has an iframe to a visualforce page:

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">

    <iframe aura:id="myFrame" id="myFrame" src="/visualforcepage"></iframe>

    <lightning:button label="Print" onclick="{! c.handleClick }" />

</aura:component>

Or LWC

   <template>
       <iframe width="100%" height="600" src={frameUrl}></iframe>
       <button onclick={handlePrint} class="slds-button slds-button_brand">Print</button>
   </template>

Using JS:

handlePrint() {
    const iframe = this.template.querySelector('iframe');
    iframe.contentWindow.focus();
    iframe.contentWindow.print();
}

I would like to press a button in the Lightning component to print the contents of the iframe.

I have tried:

window.frames['myFrame'].focus();
window.frames['myFrame'].print();

And

document.getElementById("myFrame").contentWindow.print();

And

var myFrame = cmp.find('myFrame').getElement();
myFrame.focus();
myFrame.print();

And

var myFrame = cmp.find('myFrame').getElement();
myFrame.contentWindow.focus();
myFrame.contentWindow.print();

But none of the approaches make the print dialog appear.

Question

  1. How can I fire the print() method on an iframe from within a Lightning component?
  • 1
    Consider hiding the Print button element when the button is clicked, and then just call the print() method on the top-level component – Brian Miller Jul 22 at 20:36
  • contentDocument is not supported for iframes by Locker Service. So you will not able to access it. – Dhanik Lal Sahni Jul 23 at 6:50
  • @DhanikLalSahni might be a silly question, but this is the same for LWC? – Robs Jul 23 at 7:28
  • @DhanikLalSahni would this also mean that I should be able to print like this from Visualforce? – Robs Jul 23 at 19:42
3
+50

You can use window messaging service. This is like publisher-subscriber methodology. You will add event listener in vf page and fire event from enclosing component. Below is example:

VF Page:

<apex:page >
    <div>
        Page meant for Print
    </div>
    <div>
        Page meant for Print
    </div>
    <div>
        Page meant for Print
    </div>
    <div>
        Page meant for Print
    </div>

    <script>
    var lexOrigin = "https://my-own-org-dev-ed.lightning.force.com";
    window.addEventListener("message", function(event) {
        console.log("message received => ",event,(event.data==='PRINT'));
        if (event.origin !== lexOrigin) return;
        if(event.data==='PRINT') window.print();
    }, false);
    </script>

</apex:page>

Enclosing LWC component HTML:

<template>
    <lightning-button label="Print frame" onclick={printFrame}></lightning-button>
    <iframe src="/apex/POC_PrintPage" width="600px" height="600px"></iframe>
</template>

LWC component JS:

export default class Poc extends LightningElement {
    printFrame() {
        var vfOrigin = 'https://my-own-org-dev-ed--c.ap6.visual.force.com';
        var vfWindow = this.template.querySelector('iframe').contentWindow;
        vfWindow.postMessage('PRINT', vfOrigin);
    }
}

Here are the screenshots:

display:

enter image description here

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.