Read and Insert records from a CSV file - Using Visualforce
10:07 PM
The Apex Data Loader is always there when you want to insert records into Salesforce from a CSV file. But, just in case if you don't want your users to install the Apex Data Loader and learn how to use it, then here is a simple example which tells you how to do the same using Visualforce.
Click here to view the demo.
UPDATE:
Step 1:
Download the template from here. Save the file in your desktop. Upload the file into Static Resources with the name "AccountUploadTemplate".
Step 2:
Create an Apex Class named "FileUploader". Paste the code below and save it.
Step 3:
Create a Visualforce Page named "UploadAccounts". Paste the code below and save it.
Step 4:
Download the CSV file from here for test method coverage. Upload the file with the name 'testMethodCSVUpload'
Step 5:
Create an Apex Class as shown below for test coverage.
Screenshot:
Some pointers:
Click here to view the demo.
UPDATE:
- Added special character support [Ex: French characters]
- Added TEST class coverage
Step 1:
Download the template from here. Save the file in your desktop. Upload the file into Static Resources with the name "AccountUploadTemplate".
Step 2:
Create an Apex Class named "FileUploader". Paste the code below and save it.
Step 3:
Create a Visualforce Page named "UploadAccounts". Paste the code below and save it.
Step 4:
Download the CSV file from here for test method coverage. Upload the file with the name 'testMethodCSVUpload'
Step 5:
Create an Apex Class as shown below for test coverage.
Screenshot:
Some pointers:
- You can use only the standard template. Because, that's how we have done the mapping to the columns in excel and the fields in Salesforce. You can modify the mapping and use your own template.
- Allowing the user to choose his own mapping is possible i believe, but may be a bit complex.
- Also, we use a CSV file. So, you may have to use additional criteria if your data values itself have a comma in them (For ex: Billing Street = 'Mumbai, India ') . This would cause problems because Mumbai and India would be considered as seperate values because of the comma in between them.
61 comments
VERY COOL!!
ReplyDeleteHi all. My requirement is How to read .csv file from the salesforce document folder to help with BatchApex Job and load into the salesforce org?
DeleteCan anyone help me?
Thanks
Rajesh Kumar
Salesforce Developer
Hi Rajesh,
DeleteDid you find any solution.If yes could you please help me, even i have the same requirement.
Thanks,
Surekha
I'm going to give this a try, thanks.
ReplyDeleteSounds cool!!
ReplyDeleteHey this is a great idea... I was working on something like this too... will share my code too
ReplyDeleteIts gr8....Thanks a lot for the code hint!
ReplyDeleteand the test class?
ReplyDeleteYes, very cool but would you also please advise a test class (at least for the CSV upload part)?
ReplyDeleteCoool
ReplyDeleteCan write code to read csv file from common folder and insert into contact object?
ReplyDeleteTo read from common folder and insert into Contact object you may not need this code.. You can simply schedule the Apex Data Loader to run in batch mode, you can schedule it to pick a file from a defined location and upload into salesforce
ReplyDeleteI implemented this and it was great. How did you write the test case?
ReplyDeleteI have to read the .csv file data and send it to the pdf. but in that process . i am able to send to toString() from .csv . but is in html form. so please send the steps to convert the .csv data in to the .pdf format using apex and visual force in sales force. please help for this task. u may mail me also kichepuri@gmail.com
ReplyDeleteNice bit of code. What's the maximum number of records we can insert like this? It looks like it would get caught by the 10,000 DML statement limit which means you couldn't process more than 10,000 in a single file - is that right?
ReplyDeleteThis is great! I just tried it out and it works perfectly. If only the Salesforce docs made it as clear what needs to be done as you have done. Thank you so much.
ReplyDeletecan you please send your code to me.
Deletenice thanks it's is very usefull
ReplyDeleteGreat. Thanks, its working perfectly.
ReplyDeletevery impressed...thanks...
ReplyDeleteExcellent! This works like a charm. Any way to get info on how to write a test method for it? I'm stuck at 19% and struggling. Thank again for the great write up.
ReplyDeletemstarr7@gmail.com
wow... this is a big help for me. :) Thanks!
ReplyDeleteCould you post a test method for this please. I am having difficulty getting one up to 75%. Thanks!
ReplyDeleteHi,
ReplyDeleteMe too getting no error message,it just doesn't insert.It loads the browser when i click upload file,and returns the same page.
i am also facing same pbm..Pls any one can help me..
ReplyDeleteThanks
Hi
ReplyDeleteNice work
I am getting the error "BLOB is not a valid UTF-8 string" when the csv file contains french accents (eg é,è, etc...)
Is there a solution to bypass this error?
Thanks
Hello...any workaround to solve this? i´m having the same problem here
DeleteCheers!
Hello
ReplyDeleteAny change to publish the test class for this code?
Thanks!
For everyone trying to develop a test method for this here's what I've used. It's not 100% coverage but should get you close. Mine runs at 80% for my application. Hope this helps
ReplyDelete________________________________________________
@IsTest(SeeAllData=true)
public class FileUploader_TestMethod
{ /* 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 ReadFile() {
Document lstDoc = [select id,name,Body from Document where name = 'accttest'];
// System.Debug('DOC NAME :: '+lstDoc.name);
//System.Debug('DOCBODY :: '+lstDoc.Body);
FileUploader file=new FileUploader ();
file.fileAccess();
Blob content= lstDoc.Body;
file.contentFile = content;
file.ReadFile();
file.nameFile=content.toString();
String[] filelines = new String[]{};
List accstoupload;
accstoupload = new List();
for (Integer i=1;i<filelines.size();i++)
{
String[] inputvalues = new String[]{};
inputvalues = filelines[i].split(',');
Equipment__c a = new Equipment__c();
a.Name = 'R1111111111';
a.Receiver_S__c = 'S1111111111';
a.Receiver_Model__c = '311';
a.Programming__c = 'Basic';
a.Channel__c = 'ESPN';
a.Satellite__c = '72.7';
a.Satellite_Channel__c = '100';
a.Output_Channel__c = '140';
a.RecordTypeId = '01260000000Luri';
accstoupload.add(a);
try{
insert accstoupload;
}
catch (Exception e)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please check the template');
ApexPages.addMessage(errormsg);
}
}
}
}
Thanks! How can I change the visualforce so that it'll redirect to the parent record?
ReplyDeleteI created a custom object and added a lookup field to Account. I also added a custom button in the related list.
hi
ReplyDeleteI Will try the Test class of csv File uploading . it should be 61% of my application. any help me.
ReplyDeletemy test clas code is
@isTest(SeeAllData=true)
public class FileUploader_TestMethod
{
//public static Blob contentFile{get;set;}
//public static string nameFiles{get;set;}
//static String[] filelines = new String[]{};
static Account ac;
static List accstoupload=new List();
public static testMethod void TestCase() {
{
Test.startTest();
ac=new Account();ac.Name='rakuten12345';
insert ac;
String resourceName = 'Csvfiles';
StaticResource defaultResource = [Select id,name,Body From StaticResource where Name='Csvfiles'];
Blob content= defaultResource.Body;
String myCSVFile = defaultResource .Body.toString();
System.debug('myCSVFile = ' + myCSVFile);
FBR_FileUploader file=new FBR_FileUploader();
file.contentFile = content;
file.ReadFile();
file.getuploadedAccounts();
file.nameFiles=content.toString();
String nameFiles= content.toString();
String[] filelines = nameFiles.split('\n');
accstoupload=new List();
for(Integer i=1;i<filelines.size();i++)
{
String[] inputvalues = new String[]{};
inputvalues = filelines[i].split(',');
WorkMonthly__c a = new WorkMonthly__c ();
a.Name = 'rakuten';
a.Unit__c= 'ten';
a.Date__c= System.today();
a.ImportCount__c= double.valueOf('15');
a.Account_Name__c = ac.id;
accstoupload.add(a);
try{
insert accstoupload;
System.assertEquals(1,accstoupload.size());
Test.stopTest();
}
catch (Exception e)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'An error has occured. Please check the template');
ApexPages.addMessage(errormsg);
}
}
}
}
}
Hi
ReplyDeleteNice work
I am getting the error "BLOB is not a valid UTF-8 string" when the csv file contains japanese accents . i want to japanse word in my csv file data (eg: 'プラディープ' etc...)
Is there a solution to bypass this japanese data?
Hi,
ReplyDeleteAppreciate your help.
but in this one more requirement i have, if you can help me in this also
Requirement is " In Apex data loader/import wizard, it is giving "Log File(Success file/Error File)" so can we have things in this functionality also ?
Thanks in advance
Does anyone know if there is a limit on number of records that can be uploaded? Also how about governor limits?
ReplyDeleteDoes any one know how to tailor this script to update existing records, provided the input file contains the ID. Any help would be greatly apprecated.
ReplyDeletewhat's the workaround for data that contains COMMAS ? My code is failing if data has commas.
ReplyDeleteMe too.Let me know if you got solution.Thanks
Deletecan any one help with the code, to parse a csv having double quotes and commas
DeleteThanks for this code - this solved a problem I was having. I used this for inserting an opportunity and matching product lines to load Point-of-Sales files from third parties. Code below if someone needs something similar. Please send me improvement suggestions if you have them, still learning how to write clean code.
ReplyDeletepublic class FileUploader
{
public string nameFile{get;set;}
public Blob contentFile{get;set;}
String[] filelines = new String[]{};
List oppsToUpload;
List olisToAdd;
Set oppsAdded = new Set();
List opptysToUpdate;
String pbName = [SELECT id, Name FROM PriceBook2 WHERE Name = 'Registered Partner Pricing'].id;
List opptysinserted = new List();
public Pagereference ReadFile()
{
nameFile=contentFile.toString();
filelines = nameFile.split('\n');
oppsToupload= new List();
for (Integer i=1;i();
for(Integer i=1;i getUploadedOpptys()
{
if (oppsToupload!= NULL)
if (oppsToupload.size() > 0)
return oppsToupload;
else
return null;
else
return null;
}
}
Hi,
ReplyDeleteNice post.
How to handle the below error through code :-
"BLOB is not a valid UTF-8 String"
Thanks
I think, you were trying to upload .xlsx file instead of .CSV File.
DeletePlease change the file to csv and try.
Hi,
ReplyDeleteIts really helped me allot.
Mate can you help me the same functionality for getting update the same records which we export with Id's in one column.
Hi
ReplyDeleteHow to upload excel file,reading the data from excel and how to split the fields in excel records
.
Hi,
ReplyDeleteHow to check for redundant data in the uploaded .csv file and displaying it?
Hi, What if instead of the custom Account object, I have a custom object with fields accepting different values (i.e. Employee object with employeeName, phoneNumber, startDate, salaryLevel (function) and so on..). How would I read these from csv into apex. I tried it and gets error that I cant split the different data types. I can only split if they are all of String values.
ReplyDeleteHow to handle the un inserted reocord file?if i upload again it has to insert.can u help me out
ReplyDeleteSimply Super! So helpful
ReplyDeleteNice Post admin..
ReplyDeleteHere i need to insert and update through single file which may have new records and old records.. Here we need to check based on the CCNumber(custom field) in my Custom Object. So can anyone help me regarding this...........
Thanks in advance....
Nice work!
ReplyDeleteI have a question: Is there any limitation with the number of columns and rows? I tried to import a csv with 7 columns or more and does not work but if it has 6 columns it works perfecly.
Appreciate your help.
Thanks!
hi,
ReplyDeleteif we import the more than 50000 records.then we got view state exception.how to solve this issue when we using your code for importing records
hi,
ReplyDeletethis is prakash.
i have a question from your above code,i used your code to import records from .csv file.it worked.but in my file, i increase records upto 50000.I got view state exception.please give the code to slove the above problem is more than 50000 records with sloving hte view state exception...
thanks
prakash.
Hi ,
ReplyDeleteI am not able to find apex class and vf page code.
please let me know code of vf page and class.
Regards,
Gyanender Singh
Still there are glitches while reading special char <™>
ReplyDeleteAbsolute genius. Thank you so much. I'm using it as a template for a version that imports leads captured at an exhibition. I need to reformat the data so that Salesforce accepts it. Just perfect!
ReplyDeleteI used this method (thank you!) but found it didn't handle xlsx fields that included "newline". The Blob must have some indication that delimits lines other than the \n char. Anyone know how to do this? I had to pre-process my spreadsheet before saving to csv to remove the line feeds.
ReplyDeleteThis is great! How can we use this to insert Opportunity Product Lines on an Opportunity. We want to include the VF in the opp page layout.
ReplyDeleteHas anyone adapted this code to work with Date fields or Lookup fields?
ReplyDeleteWhen I get to Line 26, I get an error if I have a field type of Date ("Error: Compile Error: Illegal assignment from String to Date at line 26 column 21"). This is because 3 lines up it is referring to a String. So how would I do the same thing with multiple field types? Picklist, Date, Number, Lookup, Text.
Thanks!
HI Guys,
ReplyDeletewe use a CSV file. So, you may have to use additional criteria if your data values itself have a comma in them (For ex: Billing Street = 'Mumbai, India ') . This would cause problems because Mumbai and India would be considered as seperate values because of the comma in between them.
How to resolve that issue?
Hi Rajesh,
ReplyDeleteEven I have the same requirement.. did you find any solution.If yes could you please help me how to resolve.
Thanks
Rekha
I wanted to read the data combination of header and values.
ReplyDeleteJan-20 Feb-20
ABC 6,716 6,716
In system, i wanted to create 2 records for Product ABC i.e 1 record with Month ->Jan and Quantity and other record with Month ->Feb and Quantity.
Any suggestions how we can do in Apex..