0

Goal: End User clicks a button on a child object's page layout that generates a PDF using merge fields from both the child and parent object records and attaches that PDF as an attachment on the child object.

I am using this Quote2PDF template guide from Salesforce's developer site as an example: Link

I wrapped the necessary VisualForce tags around an HTML/CSS document and compiled the VisualForce page successfully.

However, clicking the button results in a new window created (expected) but all HTML/CSS styling is ignored and the images are broken.

Broken PDF Screenshot Link

Notes 1. the attribute escape="false was a workaround for allowing HTML/media rich fields to display properly) 2. I uploaded a Zipped folder file with both the css file and the icons in the images folder.

<apex:page standardController = "RFP__c" showHeader="false" renderAs = "pdf" >

</head> -->
<body>
  <!--Referencing the CSS Stylesheet included in the Static Resource "rfpresources" -->
  <apex:stylesheet value="{!URLFOR($Resource.rfpresources,
          'newco-rfp.css') }" />
  <div class="header">
    <div class="header-container w-container">
      <div class="logo-area"><apex:image url="{!URLFOR($Resource.rfpresources,
          'images/logo@3x.png') }" width="160" />        
      </div>
    </div>
  </div>
  <div>
    <div class="hero w-container">
      <div class="text-hero"> Target Date:
        <apex:outputText value="{0,date,MM/dd/2016}">
         <apex:param value="{!RFP__c.Development_Initiative__r.Target_Date__c}" />
        </apex:outputText>  
      </div>
      <h2 class="h-hero">RFP for: <apex:outputText value="{!RFP__c.Development_Initiative__r.Name}" /></h2>
      <p class="text-hero-paragraph">
        <apex:outputText value="{!RFP__c.Development_Initiative__r.OVERVIEW__c}" escape="false" />
      </p>
    </div>
  </div>
  <div>
    <div class="sub-hero w-container">
      <div styleClass="sub-hero-image"><apex:image url="{!URLFOR($Resource.rfpresources, 
        'images/projectgoalsicon.png') }" width="50" />
      </div>
      <div class="sub-hero-text-title">Project Goals</div>
    </div>
    <div class="content w-container">
      <p class="paragraph">
        <apex:outputText value="{!RFP__c.Development_Initiative__r.PROJECT_GOALS__c}" escape="false" />
      </p>      
      <div class="icon-title-row">
        <apex:image styleClass="icon-title-row-image" url="{!URLFOR($Resource.rfpresources,
        'images/scopeofworkicon.png') }" width="40" />
        <h3 class="icon-title-row-text">Scope of Work &amp; Deliverables</h3>
      </div>
      <p class="paragraph">
        <apex:outputText value="{!RFP__c.Development_Initiative__r.SCOPE_OF_WORK_DELIVERABLES__c}" escape="false" />
      </p>

      <div class="icon-title-row"><apex:image styleClass="icon-title-row-image" url="{!URLFOR ($Resource.rfpresources,
         'images/userflowicon.png') }" width="40" />
        <h3 class="icon-title-row-text">User Flows</h3>
      </div>
      <p class="paragraph">
        <apex:outputText value="{!RFP__c.Development_Initiative__r.USER_FLOWS__c}" escape="false" />
      </p>

      <div class="icon-title-row"><apex:image styleClass="icon-title-row-image" url="{!URLFOR ($Resource.rfpresources,
          'images/timeline_icon.png') }" width="40" />
        <h3 class="icon-title-row-text">Timeline</h3>
      </div>
      <p class="paragraph">
        <apex:outputText value="{!RFP__c.Development_Initiative__r.TIMELINE__c}" escape="false" />
      </p>
      <div class="icon-title-row"><apex:image styleClass="icon-title-row-image" url="{!URLFOR ($Resource.rfpresources, 
        'images/technicalrequirements_icon.png') }" width="40" />
        <h3 class="icon-title-row-text">Technical Requirements</h3>
      </div>
      <p class="paragraph">The following are the technical requirements to build the app:</p>
      <ul>
        <apex:outputText value="{!RFP__c.Development_Initiative__r.TECHNICAL_REQUIREMENTS__c}" escape="false" />
      </ul>
      <div class="icon-title-row"><apex:image styleClass="icon-title-row-image" url="{!URLFOR ($Resource.rfpresources, 
        'images/criteria_icon.png') }" width="40" />
        <h3 class="icon-title-row-text">Criteria for Selection</h3>
      </div>
      <ul>
        <apex:outputText value="{!RFP__c.Development_Initiative__r.TECHNICAL_REQUIREMENTS__c}" escape="false" />
      </ul>
      <div class="icon-title-row"><apex:image styleClass="icon-title-row-image" height="44" url="{!URLFOR ($Resource.rfpresources, 
         'images/appendices_icon.png') }" width="40" />
        <h3 class="icon-title-row-text">Appendices</h3>
      </div>
      <ul>
        <apex:outputText value="{!RFP__c.Development_Initiative__r.APPENDICES__c}" escape="false" />
      </ul>
    </div>
  </div>
</body>
</apex:page>

Unlike the Quote2PDF example Salesforce gives, I did not write a controller yet because I was trying to see how much I get away with.

However, why is VisualForce not saving the HTML/CSS styling when it renders the PDF and breaking the image links as well?

  • 1
    Does it render the CSS and images from the zipped resource if you temporarily remove the renderas="pdf" attribute? This would confirm that the paths within the Zip resource are working as expected. – Daniel Ballinger Aug 27 '16 at 9:00
  • 1
    Try adding standardstylesheets="off'. doesn't appear that you'd need them for this since you're not really using anything except outputText which you seem to be styling and/or formatting with your own CSS. Beyond that, if that doesn't fix it, I'd recommend putting all of this into a Table that has no borders rather than using Divs. – crmprogdev Aug 27 '16 at 14:17
  • @crmprogdev which tag am I adding this attribute to? The <apex:stylesheet value="{!URLFOR($Resource.rfpresources, 'newco-rfp.css') }" /> tag? – GPP Aug 27 '16 at 17:07
  • 1
    It gets added to <apex:page> See the Visualforce docs for more on how it works. – crmprogdev Aug 27 '16 at 17:26
  • @DanielBallinger sorry for the thread necro, but no that did not fix it. The page looks very similar to the PDF broken page linked in the OP – GPP Apr 23 '17 at 16:48

Your Answer

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

Browse other questions tagged or ask your own question.