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

Save the PDF as a attachment in salesforce

I want to create one Custom button and on click of that button I want to open PDF.

So i created Vf page for this which is renderAS=PDF it works fine

but now When i clich on that button I want to opne the PDF and at the same time want to save the same PDF as a attachment in Attachment object in saleforce.

here is my Vf page code
<apex:page standardController="WorkOrder" showHeader="false" sidebar="false"  extensions="CustomPDFController" renderAs="pdf"  action="{!SaveAtt}" >
    <apex:form >
        <apex:pageBlock tabStyle="Account" title="Work Order">
            &nbsp;&nbsp;<apex:outputLabel value="Name : "> &nbsp;&nbsp;&nbsp;&nbsp;
            <apex:outputText value="{!wkorderlist[0].WorkOrderNumber}"></apex:outputText></apex:outputLabel>
            &nbsp;&nbsp; <apex:outputLabel value="Status : "> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <apex:outputText value="{!wkorderlist[0].status}"></apex:outputText></apex:outputLabel>
            &nbsp;&nbsp; <apex:outputLabel value="Priority : "> &nbsp;&nbsp;&nbsp;&nbsp;
            <apex:outputText value="{!wkorderlist[0].Priority}"></apex:outputText></apex:outputLabel>
        <apex:repeat value="{!MapList}" var="key">
            <apex:pageBlock title="Customer Asset Name" >
            <apex:outputText value="{!key}"/> &nbsp;&nbsp;&nbsp;
            <apex:pageBlock title="Work Order Line Items">
                <apex:pageBlockTable value="{!MapList[key]}" var="lists">
                    <apex:column value="{!lists.LineItemNumber}"/>
                    <apex:column value="{!lists.Status}"/>
                    <apex:column value="{!lists.Discount}"/>
                    <apex:column value="{!lists.DurationType}"/>
                    <apex:column value="{!lists.Priority}"/>

this is my class code

public class CustomPDFController{
    public String currentRecordId {get;set;}
    public Map<String,List<WorkOrderLineItem>> MapList {get;set;}
    public list<Customer_Asset__c> customerAssertlist {get;set;}
    public list<workorder> wkorderlist {get;set;}
    public CustomPDFController(ApexPages.StandardController stdController){
        MapList = new map<String,list<WorkOrderLineItem>>();
        currentRecordId  = ApexPages.CurrentPage().getparameters().get('id');
        system.debug('currentRecordId >>>>>>>> ' +currentRecordId);
        customerAssertlist = [select Name, Account__c,Division__c,Work_Order__c,Parent_Customer_Asset__c,(select Id,LineItemNumber,Status,Discount,DurationType,Priority from Work_Order_Line_Items__r where WorkOrderId =:currentRecordId) from Customer_Asset__c  ];
        wkorderlist = [select Id,WorkOrderNumber,status,Priority from workorder where Id =:currentRecordId];
        for(Customer_Asset__c cusAsObj : customerAssertlist){
            if(cusAsObj.Work_Order_Line_Items__r.size() > 0){
                MapList.put(cusAsObj.Name, cusAsObj.Work_Order_Line_Items__r);
        /*system.debug('MapList >>>>>>>>>>>>> ' +MapList);
         PageReference pdf = new PageReference('/apex/CustomPDFControllerSec?id='+currentRecordId);
        PageReference pdf = Page.CustomPDF;
        //prep attachment   
        //pdf.getParameters().put('id', currentRecordId);
        Attachment attach = new Attachment();
        Blob b = pdf.getContent();
        attach.Body = b;
        attach.Name = 'invoice.pdf';
        attach.IsPrivate = false;
        attach.ParentId = currentRecordId;
        //insert attach ;*/
    public void SaveAtt(){
        //PageReference pdf = new PageReference('/apex/CustomPDFv2?id='+currentRecordId);
        //prep attachment  
        PageReference pdf = Page.CustomPDF; 
        system.debug('DDEREREREGGGG '+pdf) ;
        pdf.getParameters().put('id', currentRecordId);
        Attachment attach = new Attachment();
        Blob b;
            b = pdf.getContentAsPDF();
        } catch (VisualforceException e) {
            b = Blob.valueOf('Some Text');
        system.debug('FDFDFDF '+b) ;
        attach.Body = b;
        attach.Name = 'invoice.pdf';
        attach.IsPrivate = false;
        attach.ParentId = currentRecordId;
        attach.ContentType = 'application/pdf';
        insert attach ;
    public static void emailInvoice(String RecordId){
        PageReference pdf = Page.CustomPDF; 
        pdf.getParameters().put('id', RecordId);
        //pdf.setRedirect(true); //does not seem to be required
        list<attachment> attlst =new list<attachment>();
        Messaging.Singleemailmessage mail = new Messaging.Singleemailmessage();
        Blob b = pdf.getContentAsPDF();
        system.debug('dddffdfdfd '+b) ;
        Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
        string[] toAddr = new string[] {''};
        mail.setSubject('Your Invoice from ' + UserInfo.getOrganizationName());
        mail.setHtmlBody('Thanks for attending:<b> ' + UserInfo.getOrganizationName() +' </b><p>'+
                         ' Your Invoice is attached.');
        mail.setFileAttachments(new Messaging.Emailfileattachment[] {efa}); 
        Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});  
        system.debug('Mail Sent >>>>>>>>>> ' +r);


So while opening the VF page from the custom button I am getting error as 
Too many nested getContent calls. 

So can anyone please help me out in this 


Thank you in advance

Prabhat Kumar 28Prabhat Kumar 28
I presume what is happening is that the getContent call results in a request to the same page - the ApexPages.currentPage() - and so creates another controller instance that does the same getContent call and so on.
If you put another system.debug before the getContent call I think you will see that pattern. Create a separate page and controller or pass a flag to avoid the cycle.