function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
DuFreyDuFrey 

VF page errors when rendering as pdf since the Spring 09 update

I have a custom button where I generate a VF page as a PDF with the renderAs="pdf" option by passing parameters via the query string like this:

 

/apex/QuotePDF?quoteid={!Quote__c.Id}&oppid={!Quote__c.OpportunityId__c}&ownerid={!Opportunity.OwnerId}

 

 Since the Spring 09 update, this has stopped working and gives a "Attempt to de-reference a null object" error. It appears that a value is not being populated but I am passing the VF page the necessary information needed to generate. I didn't see any mention of changes to renderAs for Spring 09. If I remove the renderAs="pdf" from the VF page, it displays without issues. Appreciate all ideas and insights.

 

Best Answer chosen by Admin (Salesforce Developers) 
dchasmandchasman

I have tracked down the root cause and am working to get a fix deployed asap - not sure on the timing just yet. I have also identified what should be a viable workaround for you in the short term.

 

The underlying issue is that in the PDF generation path your page level init action is not being invoked - if you use a constructor method instead of a page action things should work correctly again.

All Answers

dchasmandchasman
We are aware of a problem in param passing in PDF generation and are working to resolve it as quickly as possible. Just to be 100% certain that the issue I am working on is the root cause of what you have run into can you please post your pdf generation page/controller (looks like it might have started life as a copy of one of the Visualforce demo pages?)?
Message Edited by dchasman on 02-10-2009 08:56 AM
DuFreyDuFrey

Here is an abridged version of the controller and VF page:

 

 

global class Test { public Quote__c quote; public QuoteLine__c[] qlines; Integer linenum; List<QuoteWrapper> qlineslist = new List<QuoteWrapper>(); public Id quoteId = ApexPages.currentPage().getParameters().get('quoteid'); public Id oppId = ApexPages.currentPage().getParameters().get('oppid'); global class QuoteWrapper { public QuoteLine__c qline{get; set;} public Integer linenumber{get; set;} public String netprice{get; set;} } public boolean getShow(){return true;} public Decimal subTotal(List<QuoteWrapper> ql) {Decimal tempTotal = 0.0; for (QuoteWrapper qls : ql) {tempTotal += qls.qline.ext_net_price__c;} return tempTotal;} public void init() { quoteId = ApexPages.currentPage().getParameters().get('quoteid'); oppId = ApexPages.currentPage().getParameters().get('oppid'); linenum = 1; getQuote(); getAllLines(); } public Quote__c getQuote() { quote = ([SELECT Valid_Until__c, Quote_Amount__c, Opportunity__c, Opportunity__r.accountid, OwnerId, Presented_Date__c, Name, Id, Quote_Notes__c, Quote_Number__c, Quote_Discount_Price__c, Account_Name__c FROM Quote__c WHERE id = :quoteId]); return quote; } public List<QuoteLine__c> getAllLines() { qlines = ([SELECT Unit_Price__c, Unit_Net_Price__c, Sales_Discount__c, Qty_Ordered__c, Product2__c, Ext_Price__c, Ext_Net_Price__c, Display_Discount__c, Description__c, Product2__r.Family, Product2__r.ProductCode, Product2__r.Name, Product2__r.Description FROM QuoteLine__c WHERE Quote__c = :quoteId]); return qlines; } public String getquoteTotAmount() {return Utils.formatCurrency(quote.quote_discount_price__c);} public String getWirelessTotal() {return Utils.formatCurrency(subTotal(getqlinesList('Wireless', '0')));} public List<QuoteWrapper> getWirelessPrd() {return getqlinesList('Wireless', '1');} public boolean getShowWirelessPrd(){if (getqlinesList('Wireless', '0').size() == 0) {return false;} else {return true;}} public List<QuoteWrapper> getqlineslist(String family, String increment) { List<QuoteWrapper> qlineslist = new List <QuoteWrapper>(); if (qlines != null) { for (QuoteLine__c ql : qlines) { if (ql.Product2__r.Family.startswith(family)) { QuoteWrapper w = new QuoteWrapper(); w.qline = ql; w.linenumber = linenum; w.netprice = Utils.formatCurrency(ql.ext_net_price__c); if (increment == '1') {linenum++;} qlineslist.add(w); } } } return qlineslist; } }

 

 

<apex:page showHeader="false" standardStylesheets="false" Controller="Test" action="{!init}" renderAs="pdf">
<apex:pageMessages />
<apex:stylesheet value="{!$Resource.GeneralCss}" />

<apex:dataTable border="0" align="center" width="700px" columnsWidth="300px, 80px, 80px, 80px, 80px, 80px" value="{!Show}" var="a" rendered="true" >
<apex:column styleclass="LineHeader">Service</apex:column>
<apex:column styleclass="LineHeader">Quantity</apex:column>
<apex:column styleclass="LineHeader">Unit Price</apex:column>
<apex:column styleclass="LineHeader">Discount (%)</apex:column>
<apex:column styleclass="LineHeader">Discounted Price</apex:column>
<apex:column styleclass="LineHeader">Final Cost</apex:column>
</apex:dataTable>

<apex:dataTable border="0" align="center" width="700px" columnsWidth="300px, 80px, 80px, 80px, 80px, 80px" value="{!WirelessPrd}" var="qline" rendered="{!ShowWirelessPrd}" >
<apex:facet name="header"><div class="LineHeader"><br />Wireless Services</div></apex:facet>

<apex:column breakBefore="TRUE" styleclass="LineItem">
<div><apex:outputText value="{!qline.linenumber}"/>.&nbsp;&nbsp;<apex:outputText value="{!qline.qline.Product2__r.Description}"/></div>
<div><apex:outputText value="{!qline.qline.Description__c}"/></div>
<br />
</apex:column>
<apex:column styleclass="LineItem"><apex:outputField value="{!qline.qline.Qty_Ordered__c}"/></apex:column>
<apex:column styleclass="LineItem"><apex:outputField value="{!qline.qline.Unit_Price__c}"/>&nbsp;&nbsp;&nbsp;</apex:column>
<apex:column styleclass="LineItem"><apex:outputField value="{!qline.qline.Display_Discount__c}"/></apex:column>
<apex:column styleclass="LineItem"><apex:outputField value="{!qline.qline.Unit_Net_Price__c}"/></apex:column>
<apex:column styleclass="LineItem"><apex:outputField value="{!qline.qline.Ext_Net_Price__c}"/></apex:column>

<apex:column colspan="5" footervalue="Subtotal" footerclass="LineHeader"></apex:column>
<apex:column footervalue="{!WirelessTotal}" footerclass="LineHeader"></apex:column>
</apex:dataTable>

<apex:dataTable border="0" align="center" width="700px" columnsWidth="300px, 80px, 80px, 80px, 80px, 80px" value="{!Show}" var="a" rendered="true" >
<apex:column colspan="5" styleclass="LineHeader">Total</apex:column>
<apex:column styleclass="LineHeader">{!quoteTotAmount}</apex:column>
</apex:dataTable>

</apex:page>

 

The sandbox instance hasn't been updated to Spring 09 yet and still generates the PDF fine. It is no longer working in the production instance. I also notice that the CSS styles are no longer being applied to the PDF, but do not know if it is a coinedence or related.

 

Appreciate any ideas you might have since the rest of the nodes are going to be updated to Spring 09 this weekend, causing all my other generated PDFs to error in other instances.

 

dchasmandchasman

I have tracked down the root cause and am working to get a fix deployed asap - not sure on the timing just yet. I have also identified what should be a viable workaround for you in the short term.

 

The underlying issue is that in the PDF generation path your page level init action is not being invoked - if you use a constructor method instead of a page action things should work correctly again.

This was selected as the best answer
DuFreyDuFrey

Thanks Doug for the assistance. Using a constructor does cause the PDF to be generated correctly once more. I will be interested in seeing when the root cause is resolved as well.

TomSnyderTomSnyder

Having similar issues

 

I can view as pdf and html when accessing the page via the url wo/ any issues.  but when trying to render to blob in APEX via getContents() I get a 'An internal server error has occurred...'  message.

 

 

public class extContract {public Contract contract {set; get;}////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Constructor public extContract(ApexPages.StandardController controller) { this.contract = (Contract) controller.getRecord(); }////////////////////////////////////////////////////////////////////////////////////////////////////////////// public string getDateString() { datetime dt = datetime.newInstance(contract.StartDate.year(),contract.StartDate.month(),contract.StartDate.day()); return dt.format('MMMMM________yyyy'); }////////////////////////////////////////////////////////////////////////////////////////////////////////////// public PageReference saveContract() { //PageReference c = Page.compDPCContact; //PageReference p = new PageReference(c.geturl()+'?id='+contract.Id+'&pdf=1'); PageReference p = Page.DPCContract; p.getParameters().put('id', String.valueOf(contract.Id)); p.getParameters().put('pdf', '1'); Blob pdfBlob = p.getContent(); Attachment attach = new Attachment(ParentId = contract.Id, Name = 'Contract-'+datetime.now().format('yyMMddhhmmssSS')+'.pdf', Body = pdfBlob, contentType = 'application/pdf'); insert attach; PageReference RtnPage = new PageReference('/'+attach.id); return RtnPage; } }

 

 

<apex:page standardcontroller="Contract" extensions="extContract" renderAs="{!if($CurrentPage.parameters.pdf==null, null, 'pdf')}"><table style="width:8.5in;align:center"><tr><td><table style="width:6.5in"><tr><td><br></br><!-- {!dateString}<br></br> --><br></br>{!Contract.Account.Name}<br></br>{!Contract.Account.ShippingStreet}<br></br>{!Contract.Account.ShippingCity}, {!Contract.Account.ShippingState} {!Contract.Account.ShippingPostalCode}<br></br><br></br>Dear {!Contract.CustomerSigned.Name},<br></br><br></br>&nbsp;&nbsp;&nbsp;&nbsp;<apex:outputPanel id="Main" rendered="{!IF(1==1,'true','false')}">This letter sets forth the agreement ("Agreement") entered into by and between {!Contract.Account.Name} located at {!Contract.Account.ShippingStreet}, {!Contract.Account.ShippingCity}, {!Contract.Account.ShippingState} {!Contract.Account.ShippingPostalCode} ("Customer"), ...</apex:outputPanel></td></tr></table></td></tr></table><br></br><br></br><apex:form ><apex:inputHidden value="{!Contract.Id}"/><apex:inputHidden value="{!Contract.StartDate}"/><apex:commandButton action="{!saveContract}" value="Save Contract" rendered="{!if($CurrentPage.parameters.pdf==null, 'true', 'false')}"/></apex:form></apex:page>

 

 

 

 

mtbclimbermtbclimber

The fix for this was released. Please let us know if you are still having troubles with this.

 

Thanks,

Scott.MScott.M

I've just run into similar issues passing parameters to generate a pdf. One difference could by that I'm using getContent to attach the pdf to an object.

 

See this thread:

 

http://community.salesforce.com/sforce/board/message?board.id=Visualforce&message.id=10689#M10689

Message Edited by Scott.M on 03-05-2009 12:22 PM
Message Edited by Scott.M on 03-05-2009 12:23 PM
pbergmanpbergman

I'm having this issue with even the simpliest of controllers. However, I am using cookies.  I think cookies are hard on PDFs.

 

Things are fine without the renderas but putting that in kills the whole thing. Yes, I know that the cookie reference is failing.

 

Controller:

public with sharing class AgentReportController {
  public Agent__c agentObj{get;set;}
  public String agentId {get;set;}

  public AgentReportController()
    {
       Cookie cAgentId = ApexPages.currentPage().getCookies().get('agentId');
       if (!(cAgentId == null)){
            agentId = String.valueOf(cAgentId.getValue());
       }
       
       if( agentId != null){
            agentObj = [Select a.full_name__c
                            From Agent__c a where a.Id=:agentId];
       }
    }

}

 

 

Page:

<apex:page controller="AgentReportController" showheader="false" sidebar="false" cache="false" renderas="pdf">

 
<!--
       <c:RadiusAgentApplication agentId="{!agentId}"/>
-->
 
    agentid-{!agentId}-
    {!agentId}

    {!agentObj.Full_name__c}
<!--      <c:RadiusAgentApplication agentId="{!agentId}"/>
-->
                              
 
</apex:page>