4

Requirement is to upload a CSV file which carries multilingual character and Special characters into Salesforce using custom functionality [using VF and apex], but when I try to upload that file and converting blob to String getting error as 'Blob is Invalid UTF -8 String' .How to solve this issues.

Apex Class:

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<Opportunity> opptoupload;
List<Site__c> sitetoupload;
 List<String> acctNames;

List<Account> newAccts = new List<Account>();
public Pagereference ReadFile()
{
  nameFile=contentFile.toString();
  filelines = nameFile.split('\n');
  accstoupload = new List<Account>();
  contoupload = new List<Contact>();
  opptoupload = new List<Opportunity>();
  sitetoupload = new List<Site__c>();
  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.BillingStreet  = inputvalues[1];
         a.BillingCity = inputvalues[2];
         a.BillingState = inputvalues[3];
         a.BillingPostalCode = inputvalues[4];
//a.BillingCountry = inputvalues[4];
          a.Phone = inputvalues[5];
a.Website = inputvalues[6];          
          a.Fax = inputvalues[7];           


acctNames.add(a.Name);          

          acctNames.add(a.Name);

          accstoupload.add(a);
     }


    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);
         System.debug('******Sai******');
  ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'Account ' + acct.Name + ' already exists,Duplicate Account Name not allowed');
ApexPages.addMessage(errormsg);         
      }

    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))
         {
            newAccts.add(acct);
ApexPages.Message successmsg = new ApexPages.Message(ApexPages.severity.confirm,'New Account ' + acct.Name + ' is created,related Contact, Opportunity and Site record also created');
ApexPages.addMessage(successmsg);            

         }

      }

    try
    {

     insert newAccts;
    /* ApexPages.Message msg = new ApexPages.Message(ApexPages.severity.info,'AccountName with Account Id are the new Account created.Related Contact and Opportunity also created');
     ApexPages.Message msg1 = new ApexPages.Message(ApexPages.severity.info,'AccountName without Account Id are the existing Accounts');
     ApexPages.addMessage(msg);
     ApexPages.addMessage(msg1);*/

    }
     catch (Exception e)
    {

    ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'Account Name already exist, change Account Name and try again');
      ApexPages.addMessage(errormsg);

    }


//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[8];
con.Email = inputconvalues[9];
con.Phone = inputconvalues[10];

contoupload.add(con);
}}
try
{
insert contoupload;

}

catch (Exception e1)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.INFO,'Account Name associate with this Contact already exist ');
ApexPages.addMessage(errormsg);
}
// return null;

for (Integer i=1;i<filelines.size();i++)
{
String[] inputoppvalues = new String[]{};
inputoppvalues = filelines[i].split(',');

Opportunity opp = new Opportunity();
for(account a: accstoupload)
{
opp.AccountId = accstoupload[i-1].id;

}
if(opp.AccountId!= null){
opp.Name = inputoppvalues[11];
opp.CloseDate = date.parse(inputoppvalues[12]);
opp.StageName = inputoppvalues[13];
         if(opp.StageName == 'Prospecting')
            opp.Probability= 10;
         else if(opp.StageName == 'Qualification')
            opp.Probability= 10;
         else if(opp.StageName == 'Needs Analysis')
            opp.Probability= 20;
         else if(opp.StageName == 'Value Proposition ')
            opp.Probability= 50;
         else if(opp.StageName == 'Id.Decision Makers')
             opp.Probability= 60;
         else if(opp.StageName == 'Perception Analysis ')
            opp.Probability= 70;
         else if(opp.StageName == 'Proposal/Price Quote')
            opp.Probability= 75;
         else if(opp.StageName == 'Negotiation/Review')
            opp.Probability= 90;
         else if(opp.StageName == 'Closed Won')
            opp.Probability= 100;
         else if(opp.StageName == 'Closed Lost')
            opp.Probability= 0;

opptoupload.add(opp);
}
}
try
{
insert opptoupload;
}
catch (Exception e2)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please check the template or try again later');
ApexPages.addMessage(errormsg);
}
for (Integer i=1;i<filelines.size();i++)
{
String[] inputsitevalues = new String[]{};
inputsitevalues = filelines[i].split(',');

Site__c site = new Site__c();
for(account a: accstoupload)
{
site.Site_Acc__c = accstoupload[i-1].id;
//opp.AccountId = a.Id;
}

if(site.Site_Acc__c!= null)
{


site.Company_Name__c = inputsitevalues[0];
site.Company_Address__c = inputsitevalues[1];
site.Company_City__c = inputsitevalues[2];
site.Company_State__c= inputsitevalues[3];
site.Company_Postal_Code__c = inputsitevalues[4];
site.Company_Phone__c = inputsitevalues[5];
site.Company_Email__c= inputsitevalues[6];
site.Company_Fax__c = inputsitevalues[7];

site.Contact_Name__c = inputsitevalues[8];
site.Contact_Mobile__c = inputsitevalues[9];
site.Contact_Email__c = inputsitevalues[10];

site.opp_name__c = inputsitevalues[11];
site.Opp_CloseDate__c = date.parse(inputsitevalues[12]);
site.Opp_stage__c = inputsitevalues[13];
site.Name=inputsitevalues[14];

sitetoupload.add(site);
}
}
try
{
insert sitetoupload;
}
catch (Exception e3)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please check the template or try again later');
ApexPages.addMessage(errormsg);
}
return null;
}
public List<Account> getuploadedAccounts()
{

if (accstoupload!= NULL)
if (accstoupload.size() > 0)
return accstoupload;

else
return null;
else
return null;
}

public List<Contact> getuploadedContact()
{
if (contoupload!= NULL)
if (contoupload.size() > 0)
return contoupload;
else
return null;
else
return null;
}

public List<Opportunity> getuploadedOpportunity()
{
if (opptoupload!= NULL)
if (opptoupload.size() > 0)
return opptoupload;
else
return null;
else
return null;
}
public List<Site__c> getuploadedsite()
{
if (sitetoupload!= NULL)
if (sitetoupload.size() > 0)
return sitetoupload;
else
return null;
else
return null;
}
/* public pageReference fileAccess(){
Document lstDoc = [select id,name,Body from Document where name = 'test'];

System.Debug('DOC NAME :: '+lstDoc.name);
System.Debug('DOCBODY :: '+lstDoc.Body);


return null;
} */
public static testMethod void testReadFile1() {

Document lstDoc = [select id,name,Body from Document where name = 'test'];

// System.Debug('DOC NAME :: '+lstDoc.name);
//System.Debug('DOCBODY :: '+lstDoc.Body);
Data_Upload file=new Data_Upload();
Blob content= lstDoc.Body;
file.nameFile=content.toString();
}

public static testMethod void testReadFile2() {

}

}

VF Page

  <apex:pageBlock >
         <center>
          <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> -->
                         </font>
        </center>  

 <!--<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>  
       <apex:column headerValue="Account ID">
          <apex:outputField value="{!acc.Id}"/>
      </apex:column>              
  </apex:pageblocktable> 

  <apex:pageblocktable value="{!uploadedContact}" var="con" rendered="{!NOT(ISNULL(uploadedContact))}">
      <apex:column headerValue="Contact Name">
          <apex:outputField value="{!con.Lastname}"/>
      </apex:column>
      <apex:column headerValue="ContactFirstName">
          <apex:outputField value="{!con.Email}"/>
      </apex:column>
      <apex:column headerValue="Account Name">
          <apex:outputField value="{!con.AccountId}"/>
      </apex:column>
   </apex:pageblocktable>

   <apex:pageblocktable value="{!uploadedOpportunity}" var="opp" rendered="{!NOT(ISNULL(uploadedOpportunity))}">
      <apex:column headerValue="Opportunity Name">
          <apex:outputField value="{!opp.Name}"/>
      </apex:column>
      <apex:column headerValue="Account Name">
          <apex:outputField value="{!opp.AccountId}"/>
      </apex:column>
      <apex:column headerValue="Opp Date">
       <apex:outputField value="{!opp.CloseDate}"/>
      </apex:column>
      <apex:column headerValue="stage">
          <apex:outputField value="{!opp.StageName}"/>
      </apex:column>
      <apex:column headerValue="Close Date">
        <apex:outputText value="{0,date, MMMM d,  yyyy}">
        <apex:param value="{!opp.CloseDate}"/>
        </apex:outputText>
      </apex:column>          
    </apex:pageblocktable>

      <apex:pageblocktable value="{!uploadedsite}" var="site" rendered="{!NOT(ISNULL(uploadedsite))}">
      <apex:column headerValue="company Name">
          <apex:outputField value="{!site.Company_Name__c}"/>
      </apex:column>
      <apex:column headerValue="Company address">
         <apex:outputField value="{!site.Company_Address__c}"/>
      </apex:column>
      <apex:column headerValue="site Name">
          <apex:outputField value="{!site.Name}"/>
      </apex:column>                
      <apex:column headerValue="Opp_Name">
          <apex:outputField value="{!site.Opp_Name__c}"/>
      </apex:column>



       </apex:pageblocktable>      
  </apex:pageBlock>       


5
  • 1
    Make sure your csv file really is UTF-8 encoded. MS Excel does not provide a correct UTF-8 export encoding. You can find multiple VB Scripts to do the job in Excel or otherwise you just take the Excel CSV output file open it in a text editor like Notepad++ save it as a UTF-8 encoded file and do the upload again.
    – h9nry
    Aug 19, 2013 at 8:32
  • elobarate more, put some code here
    – doga
    Aug 19, 2013 at 8:56
  • 2
    Just a few feedback points on your question. Although doga asked for some code, pasting the entire implementation of your code will not lead to your question drawing much attention, as its to much work to understand all the code. You need to put some work into narrowing things down when providing code samples. If code samples are larger consider using things like Gist to post links to larger fragments. As this will also make your question easier to read at first glance. Aug 19, 2013 at 10:26
  • Also, can you provide some example data that is failing to load?
    – Mike Chale
    Aug 19, 2013 at 11:58
  • echoing @h9nry - MS Excel 2010 or earlier will NOT save CSV files in UTF-8 (I've not used later versions). However, Open Office and Google Docs will save a CSV in UTF-8 in addition to the Notepad++ suggestion.
    – cropredy
    Aug 19, 2013 at 22:23

1 Answer 1

1

Take a look at this question, 'BLOB is not a valid UTF-8 string' error?. Basically as per one of the comments on your question you do need to ensure it is a valid UTF-8 file from source. As per the answer in the related question, typically applications offer a encoding option when saving the file. Such as Notepad on Windows, select the Save As dialogue and pick the UTF8 encoding, same in Excel.

4
  • How to ensure it is a valid UTF-8 file. Aug 21, 2013 at 4:02
  • I've updated my answer with more details on this, I also see crop1645 has also provide advice on how to save. Hope this helps! :) Aug 21, 2013 at 7:18
  • @ Andrew ,We tried all this but need to do this via Apex programming. Aug 21, 2013 at 7:44
  • Ah I see, unfortunately as per the docs, Apex only supports UTF-8. This answer might be of more use to you, however it will be very heavy on the statement governor. salesforce.stackexchange.com/questions/10197/… Aug 21, 2013 at 8:30

You must log in to answer this question.

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