+ Start a Discussion
Rick SF AdminRick SF Admin 

How to define the name of a file saved from a PDF rendered visualforce page

I have a visualforce page rendered as a PDF called "Agreement" that is generated from a button on a custom object called "Agreements". The "Agreements" object has a field that identifies the Account (standard SF object) the Agreement is associated with. When saving or downloading the PDF, the name of the file is always the name of the visualforce page (Agreement.pdf). How can I define the file name when saved or downloaded as the following:

Account: Demo Tech,LLC.

Save PDF filename: Demo Tech,LLC._Agreement_Today's Date

PS. I know this has been asked before by others, but the apex class "solutions" I've read did not work for me. 

Prashant Pandey07Prashant Pandey07
Rick..I have executed the below code with account and contact..you may try to replace the contact with your custom object Agreements.

Please mark this as the best answer if this solution helped you.

 
*********Apex Code************

public class SaveAsPdfExtension {

     
    String sRetURL = System.currentPageReference().getParameters().get('sRetURL');
    String strRecordId;
    public SaveAsPDFExtension(ApexPages.StandardController controller) {
    strRecordId = controller.getId();
  
    }
    
    // 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.Fnames(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;
    }
    
    public string Fnames(String unsafeName){
     
    String allowedCharacters = '0-9a-zA-Z-_.';
    String sanitizedName = 
            unsafeName.replaceAll('[^' + allowedCharacters + ']', '');
    Account a=[select id,name from account where id=:strRecordId];
    String fieldName = a.Name;
    Date t=system.today();  
    string sets=fieldName+'_'+'Agreement_'+t+'_'+'.pdf';
    return(sets);

    }
     
}



********Visualforce Page*********

<apex:page showHeader="false" standardStylesheets="false"
    standardController="Account" extensions="SaveAsPdfExtension"
    contentType="{! renderedContentType }" renderAs="{! renderingService }">

        
    <apex:form rendered="{! renderingService != 'PDF' }"
               style="text-align: right; margin: 10px;">
        <apex:commandLink action="{! saveToPdf }" value="Save to PDF">
            <apex:param assignTo="{! renderedFileName }" value="test,,,,"/>
        </apex:commandLink>
        <hr/>
    </apex:form>
    
    <h1>Contacts for {! Account.Name}</h1>
    
    <apex:dataTable value="{! Account.Contacts }" var="contact">
        <apex:column headerValue="Name"  value="{! contact.Name  }"/>
        <apex:column headerValue="Title" value="{! contact.Title }"/>
        <apex:column headerValue="Phone" value="{! contact.Phone }"/>
        <apex:column headerValue="Email" value="{! contact.Email }"/>
    </apex:dataTable>

    <hr/>
    <!-- A little bit of info about the page's rendering; 
         see how it changes when saved as a PDF. -->
    contentType: <apex:outputText value=" {! renderedContentType }"/><br/>
    renderingService: <apex:outputText value=" {! renderingService }"/><br/>
</apex:page>

 
Rick SF AdminRick SF Admin
Rendering as PDF
Prashant Pandey07Prashant Pandey07
Could you please send your sample code..
Rick SF AdminRick SF Admin
<apex:page standardStylesheets="false" id="pge" renderAs="pdf" standardController="Agreement__c" applyHtmlTag="false" showHeader="false" extensions="SaveAsPdfExtension"
>   
<head>
    <style>
I used the created the Apex Class and it did not work.
 
Prashant Pandey07Prashant Pandey07
Got you...In the previous code standardController was account object ,you may try this and let me know if that works for you..
 
<!---Visalforce------>

<apex:page showHeader="false" standardStylesheets="false"
    standardController="Agreement__c" extensions="SaveAsPdfExtension_Test"
    contentType="{! renderedContentType }" renderAs="{! renderingService }">

  <!--See the renderAs method ...don't just use pdf..-->
        
    <apex:form rendered="{! renderingService != 'PDF' }"
               style="text-align: right; margin: 10px;">
        <apex:commandLink action="{! saveToPdf }" value="Save to PDF">
            <apex:param assignTo="{! renderedFileName }" value="test,,,,"/>
        </apex:commandLink>
        <hr/>
    </apex:form>
    
    <h1>Agreement for {!Agreement__c.Account__r.Name}</h1>
    
    <apex:dataTable value="{!Agreement__c}" var="Agreement">
       <apex:column headerValue="Name"  value="{!Agreement.Name}"/>
        <apex:column headerValue="Title" value="{! Agreement.Type__c}"/>
     
    </apex:dataTable>

    <hr/>
    <!-- A little bit of info about the page's rendering; 
         see how it changes when saved as a PDF. -->
    contentType: <apex:outputText value=" {! renderedContentType }"/><br/>
    renderingService: <apex:outputText value=" {! renderingService }"/><br/>
</apex:page>


********Apex Code**********


public with sharing class SaveAsPdfExtension_Test {

    // Required extension constructor (empty, no-op)
     
    String sRetURL = System.currentPageReference().getParameters().get('sRetURL');
    String strRecordId;
    public SaveAsPdfExtension_Test(ApexPages.StandardController controller) {
   
    strRecordId = controller.getId();
  
    }
    
    // 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.Fnames(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;
    }
    
    public string Fnames(String unsafeName){
     
    String allowedCharacters = '0-9a-zA-Z-_.';
    String sanitizedName = 
            unsafeName.replaceAll('[^' + allowedCharacters + ']', '');
    Agreement__c ag=[select id,account__c,Account__r.Name from Agreement__c where id=:strRecordId];
    String fieldName = ag.account__r.name;
    Date t=system.today();  
    string sets=fieldName+'_'+'Agreement_'+t+'_'+'.pdf';
    return(sets);

    }
    
  
}

Click the button called pdf
Click the button pdf
Click the button called Save to PDF and check the result 
User-added image

Thanks,
Prashant
Rick SF AdminRick SF Admin
Thanks but the code changed the page from a PDF to HTML. Also, i'm not adding anything to the VF page, but trying to automate the naming of the saved file. So when the button circled in red in image (A) is clicked and it opens up the browser to Save/Download the .pdf, the naming convention is automatically applied to the File name: like in imagine (B). AccountName_Agreement_Today's Date.


(A)
User-added image
(B)
User-added image