VisualForce Page:

<apex:page controller="Data_Upload">
                <apex:inputFile value="{!contentFile}" filename="{!nameFile}" />
                <apex:commandButton action="{!ReadFile}" value="Upload File" id="theButton" style="width:70px;" />
                <br/> <br/>
                <font color="red">
                    <apex:pagemessages />
                    <!--<b>Note: Please use the standard template to upload Accounts.
               <a href="{!URLFOR($Resource.AccountUploadTemplate)}" target="_blank"> Click here </a> to download the template. </b> -->
            <!--<apex:commandButton value="Access" action="{!fileAccess}"/>-->
            <apex:pageblocktable value="{!uploadedAccounts}" var="acc" rendered="{!NOT(ISNULL(uploadedAccounts))}">
                <apex:column headerValue="Account Name">
                    <apex:outputField value="{!acc.Name}" />
                <apex:column headerValue="Account ID">
                    <apex:outputField value="{!acc.Id}" />
            <apex:pageblocktable value="{!uploadedContact}" var="con" rendered="{!NOT(ISNULL(uploadedContact))}">
                <apex:column headerValue="Contact Name">
                    <apex:outputField value="{!con.Lastname}" />
                <apex:column headerValue="ContactFirstName">
                    <apex:outputField value="{!con.Email}" />
                <apex:column headerValue="Account Name">
                    <apex:outputField value="{!con.AccountId}" />

Apex :

public class Data_Upload {
    public Data_Upload(ApexPages.StandardController controller) {

    public PageReference fileAccess() {
        return null;
    public Data_Upload() {}
    public string nameFile {get;set;}
    public Blob contentFile {get;set;}
    String[] filelines = new String[] {};
    List < Account > accstoupload;
    List < Contact > contoupload;
    List < String > acctNames;
    List < Account > newAccts = new List < Account > ();
    public Pagereference ReadFile() {
        nameFile = blobToString(contentFile, 'ISO-8859-1');
        filelines = nameFile.split('\n');
        accstoupload = new List < Account > ();
        contoupload = new List < Contact > ();
        acctNames = new List < String > ();
        List < Account > existingAccts = new List < Account > ();
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] inputvalues = new String[] {};
            inputvalues = filelines[i].split(',');
            Account a = new Account();
            a.Name = inputvalues[0];
            a.billingcountry = inputvalues[1];
        existingAccts = [SELECT Id, Name FROM Account where name in: acctNames];
        //create a map with names as key
        Map < String, Id > acctNamesIdMap = new Map < String, Id > ();
        // load the map - this will help you find out if an account name exists already
        for (Account acct: existingAccts) {
            acctNamesIdMap.put(acct.Name, acct.Id);
            ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR, 'Account ' + acct.Name + ' already exists,Duplicate Account Name not allowed');
        for (Account acct: accstoupload) {
            //if account name does not exist in map, add it to list of new accounts
            if (!acctNamesIdMap.containsKey(acct.Name))
            //if (!acctNamesIdMap.containsKey(acct.Id))
                ApexPages.Message successmsg = new ApexPages.Message(ApexPages.severity.confirm, 'New Account ' + acct.Name + ' is created,related Contact also created');
        try {
            insert newAccts;
            /* ApexPages.Message msg = new ApexPages.Message(ApexPages.severity.info,'AccountName with Account Id are the new Account created.Related Contact and created');
             ApexPages.Message msg1 = new ApexPages.Message(ApexPages.severity.info,'AccountName without Account Id are the existing Accounts');
        } catch (Exception e) {
            ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR, 'Account Name already exist, change Account Name and try again');
        //return null;
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] inputconvalues = new String[] {};
            inputconvalues = filelines[i].split(',');
            Contact con = new Contact();
            for (account a: accstoupload) {
                con.AccountId = accstoupload[i - 1].id;
                //con.AccountId = a.Id;
            //con.Account= inputconvalues[0];
            if (con.AccountId != null) {
                con.Lastname = inputconvalues[2];
                con.Email = inputconvalues[3];
                con.Phone = inputconvalues[4];
        try {
            insert contoupload;

        } catch (Exception e1) {
            ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.INFO, 'Account Name associate with this Contact already exist ');
        return null;
    public List < Account > getuploadedAccounts() {
        if (accstoupload != NULL)
            if (accstoupload.size() > 0)
                return accstoupload;
                return null;
            return null;
    public List < Contact > getuploadedContact() {
        if (contoupload != NULL)
            if (contoupload.size() > 0)
                return contoupload;
                return null;
            return null;
    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);

My requirement is to upload list of parent and corresponding list of child for each parent in single save button .

Problem is how can I design to my csv file. Because initially we are calling no of filelines. Second how we can relate list of child's to parent.

let me know how we can do this ?

Thanks in advance.


Think about how you would do this using Dataloader, for example. First you have to insert the parent records, and then the children. Since you don't have their Ids yet, you should create a text field to act as an external Id in the parent objects, and then have the children assigned to them using the external Id instead of the SF Id.

I see this could be replicated in two ways:

1 - You design your code to insert first the parents (with the Ids I said), and after inserting the parents, it inserts the children assigned to the records that were inserted.

2 - You design your code and page to allow multiple processes, like a wizard. In the first process, you insert the parents (again, with the Ids I said), and then in another separate process you insert the children.

The two methods aren't that much different, but I think the second one would be easier to implement, since it is pretty much the same action, while in the first one you would have to work a little more on the logic.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.