Monday, August 22, 2016

Create record from CSV file using Apex


Upload Data without DataLoader/Import wizard in salesforce


When there is a need to load data from CSV file to salesforce, generally we use dataloader/jitterbit/import wizard    to import data in salesforce.

while using data loader or import wizard we have to configure some steps like select the object then field mapping etc.

But if there is some requirement to load data by the end user and end user not using data laoader, then we need to develop a functionality to load data using apex and visual force.

Step 1:

Create a standard template and all data should be loaded only by using this standard template

step2:

Save this standard template in Document folder so that All users who are need of it can download.

Step3:

Develop a Vf page which will have Upload csv functionality with a button having the logic to create the record to appropriate object.


Lets explore more on this....


Lets consider I want to develop Lead upload functionality  for the end user, here users are only interested to upload the lead records with field information FirstName, LastName, leadSource, email,company,Phone.

So as per step 1 and 2 , create a CSV  with all these as the header of file as template and store in document folder.

Now develop a VF page where we will have upload lead functionality, here in this page we will have a inputfile component where we will select the csv to upload and one Upload button. On click of the button Lead records will be created in the system and in below we can see the successfully created leads and the leads which are not created in the system due to some error.


Code for VF Page

<apex:page sidebar="false" controller="FileUploader" showHeader="false">
   <apex:form >
      <apex:sectionHeader title="Upload Leads from CSV file"/>
  
      <apex:pageBlock >
             <!--  Component to allow user to upload file from local machine -->
             <center>
              <apex:inputFile value="{!contentFile}" filename="{!nameFile}" /> <apex:commandButton action="{!ReadFile}" value="Upload File" id="theButton" style="width:70px;"/>
              <br/> <br/> <font color="red"> <b>Note: Please use the standard template to upload Leads. <a href="/servlet/servlet.FileDownload?file=015O00000016XLt" target="_blank"> Click here </a> to download the template. </b> </font>
             </center> 
    
      <!-- After the user clicks the 'Upload File' button, this section displays the inserted data -->
      <apex:outputText value="leads Created" rendered="{!NOT(ISNULL(uploadedLeads))}"/>
      <apex:pageblocktable value="{!uploadedLeads}" var="lead" rendered="{!NOT(ISNULL(uploadedLeads))}">
          <apex:column headerValue="First Name">
              <apex:outputField value="{!lead.FirstName}"/>
          </apex:column>
          <apex:column headerValue="Last Name">
              <apex:outputField value="{!lead.LastName}"/>
          </apex:column>
          <apex:column headerValue="Lead Source">
              <apex:outputField value="{!lead.leadSource}"/>
          </apex:column>
          <apex:column headerValue="Email">
              <apex:outputField value="{!lead.email}"/>
          </apex:column>
          <apex:column headerValue="Company">
              <apex:outputField value="{!lead.company}"/>
          </apex:column>
        
      </apex:pageblocktable>
        <apex:outputText value="leads Not Created:Due to some error" rendered="{!NOT(ISNULL(NotuploadedLeads))}"/>
       <apex:pageblocktable value="{!NotuploadedLeads}" var="lead" rendered="{!NOT(ISNULL(NotuploadedLeads))}">
          <apex:column headerValue="First Name">
              <apex:outputField value="{!lead.FirstName}"/>
          </apex:column>
          <apex:column headerValue="Last Name">
              <apex:outputField value="{!lead.LastName}"/>
          </apex:column>
          <apex:column headerValue="Lead Source">
              <apex:outputField value="{!lead.leadSource}"/>
          </apex:column>
          <apex:column headerValue="Email">
              <apex:outputField value="{!lead.email}"/>
          </apex:column>
          <apex:column headerValue="Company">
              <apex:outputField value="{!lead.company}"/>
          </apex:column>
        
      </apex:pageblocktable>
    
      </apex:pageBlock>     
   </apex:form> 
</apex:page>


Controller for this Page

public class FileUploader
{
    public string nameFile{get;set;}
    public Blob contentFile{get;set;}
    String[] filelines = new String[]{};
    List<Lead> leadstoupload;
   // List<Lead> leadsuploaded;
    /***This function reads the CSV file and inserts records into the Lead object. ***/
    public Pagereference ReadFile()
    {
        try{
                //Convert the uploaded file which is in BLOB format into a string
                nameFile =blobToString( contentFile,'ISO-8859-1');
               
                //Now sepatate every row of the excel file
                filelines = nameFile.split('\n');
               
                //Iterate through every line and create a Account record for each row
                leadstoupload= new List<lead>();
                for (Integer i=1;i<filelines.size();i++)
                {
                    String[] inputvalues = new String[]{};
                    inputvalues = filelines[i].split(',');
                   
                    lead l = new lead();
                    l.FirstName = inputvalues[0];
                    l.LastName= inputvalues[1];      
                    l.LeadSource= inputvalues[2];
                    l.Company= inputvalues[3];
                    l.Email = inputvalues[4];
                    l.phone = inputvalues[5];
                    l.Website = inputvalues[6];
                    l.Status = 'Open - Not Contacted';
                    leadstoupload.add(l);
                }
         }
         catch(Exception e){
                 ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,
                               'An error has occured reading the CSV file'+e.getMessage());
                ApexPages.addMessage(errormsg);
         }      
        //Finally, insert the collected records
        try{
            Database.SaveResult[] srList = database.insert(leadstoupload,false);
           
           for (Database.SaveResult sr : srList) {
               if (!sr.isSuccess()) {
              
                   for(Database.Error err : sr.getErrors()) {
                   }

               }

           }

           
           
           
        }
        catch (Exception e)
        {
            ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR, 
                        'An error has occured inserting the records'+e.getMessage());
            ApexPages.addMessage(errormsg);
        }   
        return null;
    }
  
   /**** This function sends back to the visualforce page the list of lead 
     records that were inserted ****/
    public List<lead> getuploadedLeads()
    {
        list<lead> leadscreated;
        if(leadstoupload!=null){
             leadscreated= new list<lead>();
            for(lead l : leadstoupload){
                if(l.id!=null){
                    leadscreated.add(l);
                }
            }
        }
        return leadscreated;
     
           
    } 
     public List<lead> getNotuploadedLeads()
    {
        list<lead> leadsNotcreated;
        if(leadstoupload!=null){
             leadsNotcreated= new list<lead>();
            for(lead l : leadstoupload){
                if(l.id==null){
                    leadsNotcreated.add(l);
                }
            }
        }
        return leadsNotcreated;
     
           
    } 
        /**
         This function convers the input CSV file in BLOB format into a string
        @param input    Blob data representing correct string in @inCharset encoding
        @param inCharset    encoding of the Blob data (for example 'ISO 8859-1')
     */
    public static String blobToString(Blob input, String inCharset){
        String hex = EncodingUtil.convertToHex(input);
        System.assertEquals(0, hex.length() & 1);
        final Integer bytesCount = hex.length() >> 1;
        String[] bytes = new String[bytesCount];
        for(Integer i = 0; i < bytesCount; ++i)
            bytes[i] =  hex.mid(i << 1, 2);
        return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
    }        
}


Output:



Create CSV template in below format and add in Document folder, user can download this template and add record information and this updated template with data can  be uploaded to the system by click on Choose file and Upload file button as per the above screen shot.



once you have uploaded lead, you can get the upload result as below screen shot.

Note: I have hard coded document id in above VF page, but we can query this lead template and get the document id whihc we can use inplace of hardcoded id.


2 comments: