0

I have a csv stored into a String named csv in controller. I have passed this string to a javascript function.The original string(in controller) had line breaks but when I download the file it is continuous i.e; in the same line though different columns values are being displayed. I want the same formatting as earlier(in tabular kind of form). Following is my controller and page code:

    public class PaginationForComponent {
            public PaginationForComponent(){
            allContactList = new list<wrapper>();
            myOrder = 'desc';
            sortField='name';
            PageNumber = 1;
            alphabet = new list<string>{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Others','All'};
            RecordsPerPageslist = 10;
            System.debug('constructor called');
            csv='';
          }
          Boolean lstNamePresent=false;
          public String objName{get;set;}
          public String fieldNames{get;set;}
          list<sObject> con = new list<sObject>();
          public String alphaSearchConct{get;set;}
          public string msg {get;set;}
          public Map<id,Boolean> m = new Map<id,boolean>(); 
          list<sObject> sortedList;
          public String myOrder{get;set;}                 // Ascending or Descending order of sorting
          public String sortField{get;set;}               // Field by which sorting should be done
          public boolean selectAll{get;set;}
          public list<String> alphabet{get;set;}
          public list<sObject> cont;
          public list<wrapper> allContactList{get;set;}
          public list<wrapper> ct = new list<wrapper>();
          public list<String> query;
          public String csv{get;set;}
        public String[] getqueryList(){
            query = fieldNames.split(',');
            for(String s:query){
              if(s=='lastname'){
                lstNamePresent=true;
              }
          }
          return query;

        }

        public void docReady(){
        con = Database.query('SELECT '+ fieldNames+' FROM '+ objName );
        System.debug('docReady con is ' + con);
        for(sObject c:(list<sObject>)stdSetController.getRecords())
              allContactList.add(new wrapper(c));
        System.debug('docReady allContactList is ' + allContactList);
      }


            public void SelectedListContacts(){         // Select contacts and save them in a map  
            for(wrapper wc:allContactList){
                m.put(wc.con.id,wc.isSelected);
                if(wc.isSelected==false){
                    selectAll=false;
                 }
            }
          }

public void submit() {
    Set<id> ids = new set<id>();
    for(id i:m.keySet()){
        if(m.get(i)==true){ 
        ids.add(i);
        }
    }
    String queryStr = 'SELECT ' + fieldNames + ' FROM ' + objName + ' WHERE id IN :ids';
    sObject[] c = Database.query(queryStr);
    String temp = '';
    for(Integer i=0;i<c.size();i++){
    for(String s: query){
       temp = String.valueOf((c[i].get(s)));
       // System.debug('before escape csv temp is ' + temp);
        if(temp!=null){
            temp = temp.escapeCsv();}
       // System.debug('temp after escapeCsv() is ' + temp);
        csv += temp;
       // System.debug('str is '+str);
        csv += ', ';
    }
    csv = csv+'\n';

  }
  System.debug('csv is >>>>>>>> '+ csv);
}

Component code is:

<apex:component controller="PaginationForComponent" allowDml="true">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
    </script>
    <script>
        function SuccessFailure(msg) {
            if(msg == '') {
                window.top.location.reload()
            } else {
                alert(msg);
            }
        }
        function cannotFind(msg){
            if(msg!=null)
                alert(msg);
        }
        $(document).ready(function(){
            funAtLast();
        });
        function downloadCsv(c){
            var csv = c;
            console.log(csv);   
            var hiddenElement = document.createElement('a');
            hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
            hiddenElement.target = '_blank';
            hiddenElement.download = 'CsvFile.csv';
            hiddenElement.click();
        }
    </script>
    <apex:attribute name="objectName" description="The object's name" type="String" required="true" assignTo="{!objName}"/>
    <apex:attribute name="fieldName" description="Fields to be displayed" type="String" required="true" assignTo="{!fieldNames}"/>
    <apex:outputPanel id="form">
        <apex:actionFunction action="{!docReady}" name="funAtLast" reRender="form,alpha,table,button"/>
       <!-- <apex:commandButton value="Process" reRender="form,alpha,table,button"/>-->
        <apex:outputPanel rendered="{!allContactList.size!=0}" id="page">
            <!-- For alphabetic search-->
                <div align="right" >
                        <apex:repeat value="{!alphabet}" var="alph" >
                            <apex:commandLink value="{!alph}  " action="{!alphaSearch}" oncomplete="cannotFind('{!msg}');" reRender="table,button" styleClass="bghover" style="text-decoration: none;padding: " > &ensp;
                                <style type="text/css">
                                    .bghover:hover{
                                        background-color: #b3ffff;
                                    }
                                </style>
                                <apex:param name="a" value="{!alph}" assignTo="{!alphaSearchConct}"/>
                            </apex:commandLink>
                        </apex:repeat>
                </div>
            <apex:pageBlock id="table">
                <!-- To delete selected records-->
                <apex:commandButton action="{!DelSelected}" value="Delete Selected" oncomplete="SuccessFailure('{!msg}');"/>
                <!-- Button for csv download -->
                <apex:commandButton action="{!submit}" value="Download CSV" reRender="none" oncomplete="downloadCsv('{!csv}')"/>
                <apex:pageMessages rendered="true" id="Msg"/>
                <apex:PageBlockTable value="{!WrapperContacts}" var="contacts">
                    <!-- To Edit and Delete a record -->
                   <apex:column headerValue="Action">
                        <apex:outputLink value="{!URLFOR($Action[objectName].Edit,contacts.con.id)}">
                            Edit |
                        </apex:outputLink>
                        <apex:outputLink value="{!URLFOR($Action[objectName].Delete,contacts.con.id)}"> 
                            Del |
                        </apex:outputLink>
                    </apex:column>
                    <apex:column >
                    <apex:facet name="header">
                            <apex:inputCheckbox value="{!selectAll}">  
                                <apex:actionSupport event="onclick" action="{!SelectedAllContacts}" reRender="table"/>
                                </apex:inputCheckbox>  
                            </apex:facet>
                        <apex:inputCheckbox value="{!contacts.isSelected}">
                            <apex:actionSupport event="onclick" action="{!SelectedListContacts}" reRender="none" />
                        </apex:inputCheckbox> 
                    </apex:column>
                    <apex:repeat value="{!queryList}" var="fldNames">
                        <apex:column >
                            <apex:facet name="header">
                                <apex:commandLink value="{!fldNames}" action="{!toggleSort}" reRender="table">
                                    <apex:param name="sortField" value="{!fldNames}" assignTo="{!sortField}" />
                                    <apex:param name="myOrder" value="{!IF(myOrder == 'DESC', 'ASC','DESC')}" assignTo="{!myOrder}" />
                                </apex:commandLink>
                            </apex:facet>
                            {!contacts.con[fldNames]}
                        </apex:column>
                    </apex:repeat>
                </apex:PageBlockTable>
            </apex:pageBlock>
            <apex:outputPanel id="button"> 
                <div align = "center" >
                    <!-- To return to first page of records-->
                    <apex:commandButton action="{!first}" value="<<" title="First Page" disabled="{!!HasPrevious}" reRender="table,button"/>
                    <!-- To return to Previous page of records-->
                    <apex:commandButton action="{!previous}" value="Previous" disabled="{!!HasPrevious}" reRender="table,button"/>
                    <!-- To return to next page of records-->
                    <apex:commandButton action="{!next}" value="Next >" disabled = "{!!HasNext}" reRender="table,button"/>
                    <!-- To return to last page of records-->
                    <apex:commandButton action="{!last}" value=">>" title="Last Page" disabled="{!!HasNext}" reRender="table,button"/>
                    <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
                    <span style="float:right">
                        <apex:outputLabel value="Page ">
                        </apex:outputLabel>
                         <!-- To navigate to the page--> 
                        <apex:InputText value="{!PageNumber}" maxLength="4" size="1">
                        <apex:actionSupport event="onchange" action="{!NavigateByText}"  reRender="table,button"/>
                        </apex:InputText>
                         <!-- The above action support is not working-->         
                        <apex:outputLabel value=" of {!TotalPages}">
                        </apex:outputLabel>
                    </span>
                    <!-- To display a list for number of records to be selected per page-->
                    <span style = "float:left">
                        <apex:SelectList value="{!RecordsPerPageslist}" size="1" >
                            <apex:selectOptions value="{!RecordsPerPageOptionList}">    
                            </apex:selectOptions>
                            <apex:actionSupport event="onchange" action="{!ChangeNumberOfRecordsPerPage}" reRender="table,button"/>
                        </apex:SelectList>
                    </span>
                </div>
            </apex:outputPanel>    
        </apex:outputPanel> 
    </apex:outputPanel>
</apex:component>

PS: I have tried to provide only relevant code here, my csv download should begin on pressing the submit button

2
  • Your local text editor may be looking for different line endings. Are you using an IDE or developer's editor?
    – David Reed
    Commented May 6, 2018 at 18:22
  • I am writing my code on sublime editor and my org is developer edition Commented May 6, 2018 at 18:37

1 Answer 1

2

You have to use JSENCODE function to pass the new line character to the JavaScript function.

JSENCODE : Encodes text and merge field values for use in JavaScript by inserting escape characters, such as a backslash (), before unsafe JavaScript characters, such as the apostrophe (').

In your Apex controller, you have to add \n as the line break and by using JSENCODE in VF page you will get the same formatting. You can use it like this in your code.

VF Page

<apex:page controller="CSVController" >
    <script>
    function downloadCsv(c){
        var csv = c;
        console.log(csv);   
        var hiddenElement = document.createElement('a');
        hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
        hiddenElement.target = '_blank';
        hiddenElement.download = 'CsvFile.csv';
        hiddenElement.click();
    }
    </script>
    <apex:form>
        <apex:commandButton action="{!submit}" value="Download CSV" reRender="none" oncomplete="downloadCsv('{!JSENCODE(csvStr)}')"/>
    </apex:form>
</apex:page>

Apex Controller

public class CSVController {
    public String csvStr {get;set;}
    public CSVController(){
        csvStr = 'a,b,c\nd,e,f';
    }
    public pageReference submit(){
        return null;
    }
}
1
  • Thanks Saroj it was of lot of help. I am also encountering another problem, Although i have used String.csv() method but still some texts are not formatted properly. Eg: "United Oil & Gas UK".This whole should be in a single column but it is appearing in 2 different columns Commented May 7, 2018 at 7:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .