1

@Andrei.Z

Here is what I'm talking about:

enter image description here

Here is my new .csv updated:

Employee_Name__c,Employee_Status__c
Erich Schulz,Active
Joe Dohn,Active
Walter Anderson,InActive
David Hudson,InActive

END

I'm have the following code i'm trying to import the .csv file but it does not looks like its not even going through the loop to display the data in <apex:pageblocktable, so what is happening is that, i browse and select the .csv file and click on upload csv button and does not loop the data and show it in pageblocktable. i have few records as shown below.

I'm following this reference link

I have the following .csv data file:

Employee Name,Employee Status
Erich Schulz,Active
Joe Dohn,Active
Walter Anderson,InActive
David Hudson,InActive

Visualforce page:

<apex:page controller="importDataFromCSVController" title="Contacts Uploader">
    <style>
        .controlPanel td{
            width:200px;
        }
        .controlPanel{
            margin-top:20px;
        }
    </style>    
    <apex:form >                    
        <apex:pageBlock id="controlPanel">                        
            <table class="controlPanel fromFile">
                <tr>
                    <td colspan="2"><b>Upload a CSV file to save its contents as Contact records</b></td>
                </tr>
                <tr>
                    <td>Upload CSV file</td><td><apex:inputFile value="{!csvFileBody}" accept="csv" contentType="text/csv" /></td>
                </tr>
                <tr>
                    <td>&nbsp;</td><td><apex:commandButton value="Upload CSV" action="{!readFromFile}"/></td>
                </tr>
            </table>                                                             
        </apex:pageBlock>
        <apex:pageBlock id="dataPanel">
            <apex:pagemessages />
            <apex:pageblocktable value="{!lstContacts}" var="con">
                <apex:repeat value="{!lstFieldNames}" var="fieldName">
                    <apex:column value="{!con[fieldName]}" />
                </apex:repeat>                
            </apex:pageblocktable>
            <apex:commandButton value="Save to Contacts" action="{!saveData}" rendered="{!readSuccess}" />
        </apex:pageBlock>
    </apex:form>        
</apex:page>

Apex code:

public class importDataFromCSVController {

    public String documentName {get;set;}
    public Blob csvFileBody{get;set;}
    public String[] contactDataLines {get;set;}
    public List <Employee_Upload__c> lstContacts {get;set;}
    public boolean readSuccess {get;set;}
    public List<String> lstFieldNames{get;set;}
    Employee_Upload__c conObj;
    String contactDataAsString;
    String fieldValue;
    Integer fieldNumber;
    Map <String, Integer> fieldNumberMap = new Map < String, Integer > ();

  public importDataFromCSVController() 
  {
    documentName = '';
    readSuccess = FALSE;
    contactDataLines = new String[] {};
    lstContacts = new List <Employee_Upload__c> ();
        lstFieldNames = new List<String>();
  }
    public void readFromFile(){
        try{
            contactDataAsString = csvFileBody.toString();
               system.debug('contactDataAsString ' +contactDataAsString );
            readCSVFile();
        }
        catch(exception e){
            readSuccess = FALSE;
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.Severity.ERROR,'Error reading CSV file');
            ApexPages.addMessage(errorMessage);
        }
    }    
  public void readCSVFile() {
    lstContacts.clear();
        contactDataLines = contactDataAsString.split('\n');
        string[] csvFieldNames = contactDataLines[0].split(',');
        for (Integer i = 0; i < csvFieldNames.size(); i++) {
            fieldNumberMap.put(csvFieldNames[i], i);
            lstFieldNames.add(csvFieldNames[i].trim());
        }

        system.debug('contactDataLines ' +contactDataLines);

        for (Integer i = 1; i < contactDataLines.size(); i++) {
            conObj = new Employee_Upload__c();
            string[] csvRecordData = contactDataLines[i].split(',');
            for (String fieldName: csvFieldNames) {
                fieldNumber = fieldNumberMap.get(fieldName);
                fieldValue = csvRecordData[fieldNumber];
                conObj.put(fieldName.trim(), fieldValue.trim());
            }
            lstContacts.add(conObj);                
        }
        if(lstContacts.size() > 0){
            readSuccess = TRUE;
        }            
  }
  public void saveData() {
    try {
      //INSERT lstContacts;
      ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.INFO, 'Contact records inserted successfully');
      ApexPages.addMessage(errorMessage);
    } catch (Exception e) {
      ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.severity.ERROR, 'An error has occured while saving data');
      ApexPages.addMessage(errorMessage);
    }
  }
}
4
  • (1) what does your debug line contactDataLines show? (2) add rerender="datapanel" to your commandButton; (3) as an aside - this is a somewhat fragile csv parser but might be OK for your limited use case (a) column names must be sobject fieldname and b) no support for embedded cell value of comma or line break.
    – cropredy
    May 30, 2016 at 23:54
  • 1) i see my .csv data 4 rows 2) if i add rerender on commandButton i'm getting this error apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute. 3) do you know any better csv parser? i have added sobject fieldname please see my updated question
    – Nick
    May 31, 2016 at 0:25
  • Instead of this : contactDataLines = contactDataAsString.split('\n'); try contactDataLines = contactDataAsString.split('\r'); and get a count of the number of lines in your CSV record. May 31, 2016 at 2:07
  • @RichardDurrant: it does work after changing from \n to \r, post this as answer.
    – Nick
    May 31, 2016 at 12:56

4 Answers 4

0

Change the \n to \r and you should get the correct number of rows in the contactDataLines variable.

0

the problem is inside your CSV file Header must contain API names, not labels, change

Employee Name 

to

Employee_Name__c

this is a prediction as you do not show object, API name can be different. I tried this on Contact and custom fields in Contact and works fine.

object screenshot example enter image description here

4
  • did you tried the exact code i have posted? if i replace the employee name to employee_name__c i still do not see except that first record employee name on the employee status, please see my edit post and i'm going to post the screen shot... this is really driving me crazy...
    – Nick
    May 31, 2016 at 0:05
  • please show your new CSV, and object screenshot , so those 2 fields description and types are visible
    – Andrei.Z
    May 31, 2016 at 0:09
  • Please see my updated question i have screenshot and .csv updated
    – Nick
    May 31, 2016 at 0:16
  • it is working fine for me, again I am trying with custom fields on Contact. Can you give me screenshot of your Employee_Upload__c object. I give one from contact as example.
    – Andrei.Z
    May 31, 2016 at 0:29
0

@Nick Kahn, I tried the exact code you have posted and its working fine with record insertion as Andrei.Z said, if your custom fields look like below:

Employee_Upload__c

or

you can use the Standard field 'Name' (80 chars limit) instead of custom field (Employee_Name__c), then need to change input CSV as Name,Employee_Status__c

0

I have tried your exact code and link its perfectly working ,

Important Point CSV file Header must contain API names, not labels

You must log in to answer this question.

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