Wednesday, August 7, 2013

How to give a name while export a file in csv/xls

Hi friends, recently I came across a situation where client want's to give a name while exporting a file in csv/xls. In salesforce we can not code in such a way that it will ask you any name before save the file at your local drive. Alternate solution is we can pass different names from the different pages, so we can distinguish in between two exported files from different pages. Here is the detail how you can do this.

We need to create below resources for it-

#1-BlogCSV.page
#2-BlogCSV.component
#3-BlogCSVController.cls
#4-ExportTestPage.page


let me take this one by one & tell you how we can pass name while export in this.

#1-BlogCSV.page 
This is a VF page which generate a xls file for given table.
here the important thing is we will pass contenttype attribute something like below





contentType="application/vnd.ms-excel#{!SUBSTITUTE($CurrentPage.parameters.page,'XXXXXX__','')}_YOUR_POSTFIX_HERE.xls"

in this the exported file name will be build by Page Name from where it is exported + your postfix whatever you give in above content type attribute.

here is the complete code for this-
<apex:page language="en-US" cache="false" readonly="true" sidebar="false" showHeader="false" pageStyle="false" contentType="application/vnd.ms-excel#{!SUBSTITUTE($CurrentPage.parameters.page,'PackagePrefix__','')}_YOUR_POSTFIX_HERE.xls">
  <c:BlogCSV id="csvComponent1" />
</apex:page>


#2-BlogCSV.component 
this component is simply rendering the account table which will be going to export.
<apex:component controller="BlogCSVController" id="component1">
 <apex:pageBlock >
        <apex:pageBlockTable value="{!lstOfAccount}" var="lst" width="100%" rendered="{!IF(lstOfAccount.Size>0,true,false)}">
         <apex:column >
                  <apex:facet name="header" >
                    Name
                  </apex:facet>
                  <apex:outputLink value="{!lst.id}" >{!lst.Name}</apex:outputLink>  
              </apex:column>
              <apex:column >
                  <apex:facet name="header" > 
                     AccountSource
                  </apex:facet>
                  <apex:outputLabel value="{!lst.AccountSource}" />  
              </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>    
</apex:component>

#3-BlogCSVController.cls
this class is common controller class for both component & page. here is the code for this -
public with sharing class BlogCSVController {
 public string currentPage {get;set;} 
 public String redirectURL {get;set;}
  public PageReference Export(){
     
     
     PageReference pr = Page.BlogCSV;
     pr.getParameters().put('page',currentPage);
     redirectURL = pr.getUrl(); 
     return null; 
    }
    
 public List lstOfAccount{get;set;}
 public BlogCSVController(){
  lstOfAccount = [Select Id,Name, AccountSource from Account LIMIT 10];
 }
}

#4-ExportTestPage.page
finally this is the page where will provide export button which will initiate export.Here is the code-
<apex:page controller="BlogCSVController">
 <apex:form id="form1">
  <apex:pageMessages id="msg" />
  <apex:sectionHeader Title="Export" subtitle="XLS Sample" /> 
  <apex:pageBlock id="block1">
   <apex:pageBlockButtons location="top">
    <input type="button" class="btn" value="Export" onclick="Export('{!$CurrentPage.Name}');" />
                  <apex:actionStatus id="statusLoadingMain">
                      <apex:facet name="start">
                              <span style="font-weight:bold; color: red;">
                                  Please wait while exporting...<img src="/img/loading.gif" /> 
                              </span> 
                      </apex:facet>
                  </apex:actionStatus>
              </apex:pageBlockButtons>
   
   <script>
     function Export(pagename){
             jsExport(pagename);
          } 
   </script>
    
    <apex:outputPanel id="pnlExport"> 
             <script>
                 if("{!redirectURL}" != ""){
                     window.location.href="{!redirectURL}";
                 }
             </script>
         </apex:outputPanel>
         <apex:actionFunction status="statusLoadingMain" name="jsExport" action="{!Export}" rerender="pnlExport,msg">
                     <apex:param name="currentPage" id="currentPage" value="" assignto="{!currentPage}" />
                   </apex:actionFunction>
   </apex:pageBlock>     
   <c:BlogCSV id="csvComponent1" />    
 </apex:form>          
</apex:page>

here notice that we are passing current page name in action function.
Now when you click on export this will be exported with your page name & given postfix.
You can see a demo here