+ Start a Discussion
Linda 98Linda 98 

Custom button to Generate PDF,Save it in attachments and email it.

Hi i am having a custom button,which when clicked generates the PDF and saves it in attachment.
Now i am trying to make it as email too.
so when the custom button is clicked,generate pdf ,save the pdf to attachment and email it to particular user email.

How can i do it?Can i do it on single button?Or do i need two buttons. 1 .generate and save
2.email pdf?
I am confused and struck here .I am able to generate it and save as attachment.
But i want all three steps(generate,save and email) in single button.Please help.
Thanks in advance.
Chris Gary CloudPerformerChris Gary CloudPerformer
You can perform all of this in a single button.  The amount of code, however, may be a different story.
First, if you are trying to generate a custom PDF on Salesforce from a Visualforce Page, then you will need to develop the needed Visualforce Page, and its related controller, if necessary. 
Then you will need to create a class that exposes a webservice method and does a couple of things:
1. It will need to call the page - using the PageReference.getContentAsPDF() method. This will return a Blob
2. You can then create the Attachment Record (using the Blob returned from the previous step) and relate it to the Parent Record. Save this.
3. You can also then use the Blob record to create the EmailAttachment and then create the email and send it off.
Once this is complete, you will need to create your button, which is essentially a javascript button that will use the sforce javascript library to call the method that is exposed as a web service.
Below is an example of the class that will generate the PDF, Save the attachement, and email it:
global class PDFGenerationClass {
    static webservice Id GenerateCustomPDFAndEmail(Id recordId){
        //first we need to get the page
        PageReference defaultPage = new PageReference('/apex/PDFPage'); //page location
        defaultPage.getParameters().put('id',quoteId); //passing in id for specific record
        Blob pageData; //variable to hold binary PDF data.
        if(!Test.isRunningTest()){ // for code coverage 
            pageData = defaultPage.getContentAsPDF();
        } else {
            pageData = Blob.valueOf('This is a test.');
        }
        //create attachment
        Attachment att = new Attachment(
            					ParentId=recordId,
            					Body=pageData,
            					Name='Quote ' + DateTime.now().formatLong() + '.pdf'
        					);
       	insert att;
        //create and send email 
       	Messaging.EmailFileAttachment att = new Messaging.EmailFileAttachment();
       	att.setBody(pageData);
       	att.setContentType('application/pdf');
       	att.setFileName('attachment.pdf');
       	Messaging.SingleEmailMessage mess = new Messaging.SingleEmailMessage();
       	mess.setSubject('Email');
       	mess.setToAddresses(new String[]{'somebody@blah.com'});
       	mess.setPlanTextBody('Here is your attachment.');
       	mess.setFileAttachments(new Messaging.EmailFileAttachment[]{att});
       	Messaging.sendEmail(new Messaging.Email[]{mess},false);
        //return the Id of the attachment that was created and emailed
        return att.Id;
    }

Below is an example of what Javascript would go into the button:
{!REQUIRESCRIPT("/soap/ajax/38.0/connection.js")} //include required Javascript
{!REQUIRESCRIPT("/soap/ajax/29.0/apex.js")} //included needed Javascript
//call the acutal service method
var result = sforce.apex.execute("PDFGenerationClass","GenerateCustomPDFAndEmail",{recordId:"{!record.Id}"}); 
if(result != null){ 
window.alert('PDF Generated.'); 
window.location.reload(); 
}

There you have it.
Josef LagorioJosef Lagorio
Ran in to this error using your above code: 
Error: Compile Error: Duplicate variable: att (attempt to re-create the variable with type: EmailFileAttachment) at line 20 column 39
Chris Gary CloudPerformerChris Gary CloudPerformer
Ahh yes, apologies for that.  Here is some updated code:
global class PDFGenerationClass {
    static webservice Id GenerateCustomPDFAndEmail(Id recordId){
        //first we need to get the page
        PageReference defaultPage = new PageReference('/apex/PDFPage'); //page location
        defaultPage.getParameters().put('id',quoteId); //passing in id for specific record
        Blob pageData; //variable to hold binary PDF data.
        if(!Test.isRunningTest()){ // for code coverage 
            pageData = defaultPage.getContentAsPDF();
        } else {
            pageData = Blob.valueOf('This is a test.');
        }
        //create attachment
        Attachment att = new Attachment(
            					ParentId=recordId,
            					Body=pageData,
            					Name='Quote ' + DateTime.now().formatLong() + '.pdf'
        					);
       	insert att;
        //create and send email 
       	Messaging.EmailFileAttachment mailAtt = new Messaging.EmailFileAttachment();
       	mailAtt.setBody(pageData);
       	mailAtt.setContentType('application/pdf');
       	mailAtt.setFileName('attachment.pdf');
       	Messaging.SingleEmailMessage mess = new Messaging.SingleEmailMessage();
       	mess.setSubject('Email');
       	mess.setToAddresses(new String[]{'somebody@blah.com'});
       	mess.setPlanTextBody('Here is your attachment.');
       	mess.setFileAttachments(new Messaging.EmailFileAttachment[]{mailAtt});
       	Messaging.sendEmail(new Messaging.Email[]{mess},false);
        //return the Id of the attachment that was created and emailed
        return att.Id;
    }

 
Rick SF AdminRick SF Admin
Hello Linda 98,

Can you share the code that you used for generating the PDF and saves it in attachment on within the record on Object please? I have a code on my custom object that creates the PDF file, however I would like when the button is selected that it also attaches the PDF to the record. Thanks.
Ash Jones 10Ash Jones 10
Hi Chris Gary CloudPerformer,
Can you please help me with this? I am getting the error Variable doesnt exist quoteId.
Chris Gary CloudPerformerChris Gary CloudPerformer
Hi Biren,

in line 5, replace 'quoteId' with the name of the variable you are passing in as the Id. in my example, it would be 'recordId'. Hope that helps.
Ash Jones 10Ash Jones 10
Hi Chris
I am sorry to bother you again. What do you mean by variable you are passing in as the Id? I used recordId at the class and it did not give me an error but when i am creating a button the javascript gave me an error
Field record.Id does not exist. Check spelling.
If i post my VF page & class code will it help you?
I really appreciate your help.
Ash Jones 10Ash Jones 10
Hi Chris,
I was able to fix the issue after playing around. One question about mess.setToAddresses(new String[]{'somebody@blah.com'});
what should be the value for 'somebody@blah.com'? Can user type in an email address they want to send the document?
Chris Gary CloudPerformerChris Gary CloudPerformer
Biren - 
If you are calling this webservice class from a Visualforce button, then if you know a decent amount of Javascript, then you may be able to pop an input box and send the value of the input to the method call.  You will need to add an additional parameter to the webservice method representing the email address in order to utilize it within the code. Best of luck to you.  It seems like my answer is helping you, so please feel free to mark as 'Best Answer'.  Thanks!
Asha Kumari 1Asha Kumari 1
Hi Ash,

How did you fix that issue? I am also getting the same error.

Thanks,
AK
Sayandip ghoshSayandip ghosh
Hi Chris,

The Page "PDFPage" is a different VF page right? Because in my code i have a requirement like ApexPages.currentPage().getContentAsPDF(); it is throwing 
"common.apex.runtime.impl.ExecutionException: Exception common.page.PageInterruptException, Cyclical server-side forwards detected: /apex/UpgradeAdvisor?inline=1"|0x72885936

Can you please help

Thanks,
Sayandip
Sebastian BecerraSebastian Becerra

Hey Ash!

I am getting the same error message, could you please tell us how you solved it?

Is that an Id that I should pass from the Visualforce Page or from the Record page?
Thanks a lot!
Sebastian