0

I have a Lightning Component, that is iframing a VF Page which displays a plain text Static Resource. The VF Page has a text placeholder 'CONTACTNAME' that is replaced with Contact.Name which is sent from the Lightning Component. The VF Page first renders as HTML, but there is a button to convert to PDF for download. When I click the button to switch to PDF, it renders the original text with the placeholder 'CONTACTNAME' instead of Contact.Name.

How can I make sure that when converted to PDF, the data carries over?

Visual Force Page:

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" applyBodyTag="false" controller="AddCreditCardController"
    contentType="{!renderedContentType}" renderAs="{!renderingService}">

    <style>
        body {
            font-family: 'Helvetica', 'Arial Unicode MS';
            font-size: 12px;
            line-height: 200%;
        }

        .downloadLink {
            font-family: "Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace;
        }
    </style>

    <body>
        <apex:form rendered="{!renderingService != 'PDF'}" style="text-align: right; margin: 10px;">
            <apex:commandLink action="{!saveToPdf}" value="Download PDF">
                <apex:param assignTo="{!renderedFileName}" value="Credit-Card-Consent.pdf" />
            </apex:commandLink>
            <hr/>
        </apex:form>

        <apex:outputText id="consentName" value="{!ccConsentText}">
        </apex:outputText>

        <script>
            var contactName = '{!$CurrentPage.parameters.contact_Name}';
            console.log(contactName);
            var consentText = document.getElementById('{!$Component.consentName}').textContent.replace('CONTACTNAME', contactName);
            document.getElementById('{!$Component.consentName}').textContent = consentText;
        </script>
    </body>
</apex:page>

Lightning Component iframe:

<iframe
                        aura:id="consentFrame"
                        src="{!'https://' + v.consentHost + '/apex/CreditCardConsent?type=publicLink&amp;contact_Name='+ v.Contact.Name}"
                        width="100%"
                        height="375"
                        frameBorder="1"
                        scrolling="yes"
                    />

Controller for Rendering:

 public String ccConsentText {
        get {
            StaticResource sr = [
                    select Body
                    from StaticResource
                    where Name = 'CreditCardConsentTerms'
                    ];
            String consentText = sr.Body.toString();
            return consentText;
        }
    }

     // Determines what kind of rendering to use for the page request
    public String renderingService { get; private set; }

    // Allow the page to set the PDF file name
    public String renderedFileName { 
        get; 
        set { renderedFileName = this.sanitizeFileName(value); }
    }

    // Rendered content MIME type, used to affect HTTP response
    public String renderedContentType {
        get {
            String renderedContentType = 'text/html'; // the default

            if( ! this.renderingAsHtml() ) {
                // Provides a MIME type for a PDF document 
                renderedContentType = 'application/pdf';

                // Add a file name for the PDF file
                if( this.renderedFileName != null) {
                    // This is supposed to set the file name, but it doesn't work
                    renderedContentType += '#' + this.renderedFileName;

                    // This is a work-around to set the file name
                    ApexPages.currentPage().getHeaders().put(
                        'content-disposition', 'attachment; filename=' + 
                         this.renderedFileName);
                }
            }

            return renderedContentType;
        }
    }

    // Are we rendering to HTML or PDF?
    public Boolean renderingAsHtml() {
        return ( (renderingService == null) || 
                 ( ! renderingService.startsWith('PDF')) );
    }

    // Action method to save (or "print") to PDF
    public PageReference saveToPdf() {
        renderingService = 'PDF';
        return null;
    }

    // Private helper -- basic, conservative santization
    private String sanitizeFileName(String unsafeName) {
        String allowedCharacters = '0-9a-zA-Z-_.';
        String sanitizedName = 
            unsafeName.replaceAll('[^' + allowedCharacters + ']', '');
        // You might also want to check filename length, 
        // that the filename ends in '.pdf', etc.
        return(sanitizedName);
    }
0

The PDF feature cannot execute JavaScript. As such, you can't use Lightning components in a PDF. You'll need to code your page issuing normal HTML or Visualforce components instead.

2
  • Right but it originally renders as plain HTML Text, runs the javascript and replaces. So I would assume when it renders as PDF at the click of the button it would render the text on the page, or is it rendering directly from the static resource file? Nov 7 '19 at 14:51
  • @PatrickShee the renderer can't read the client's HTML. It is generated on the server without prior page state. It also can't run JavaScript. Anything that isn't immediately available the instant the page loads can't apart in the PDF.
    – sfdcfox
    Nov 7 '19 at 14:59

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.