Skip to content

Instantly share code, notes, and snippets.

@nicocrm
Created March 7, 2011 04:50
Show Gist options
  • Save nicocrm/858086 to your computer and use it in GitHub Desktop.
Save nicocrm/858086 to your computer and use it in GitHub Desktop.
SalesForce Apex CSV Parser
/**
* Used to read a delimited file.
*/
public class SSSCsvReader {
private String delim = ',';
// the input data
private String[] buffer;
public SSSCsvReader(String data){
this.buffer = data.split('\n');
}
public SSSCsvReader(String data, String delim){
this.buffer = data.split('\n');
this.delim = delim;
}
/**
* Read and parse next available line. Return null if end of stream.
*/
public String[] readLine(){
if(buffer.size() == 0)
return null;
String line = this.buffer.remove(0);
String[] parts = new String[] {};
while(line != ''){
Integer next = 0;
if(line.startsWith('"')){
line = line.substring(1); // strip initial
Integer quoteIndex = findQuote(line, 0);
while(quoteIndex == -1){
if(buffer.size() == 0){
// EOT!
quoteIndex = line.length();
} else {
// grab the next line
Integer skip = line.length();
line += '\n' + this.buffer.remove(0);
quoteIndex = findQuote(line, skip);
}
}
// advance to comma
next = quoteIndex + 1;
parts.add(line.substring(0, quoteIndex).replace('""', '"'));
} else {
next = line.indexOf(this.delim, next);
if(next == -1)
next = line.length();
// NB in Substring, "endindex" is the index of the character AFTER the last index to get
parts.add(line.substring(0, next));
}
if(next == line.length() - 1)
// case of a terminating comma.
parts.add('');
line = next < line.length() ? line.substring(next+1) : '';
}
if(parts.size() == 0)
// empty string - we still want to return something...
parts.add('');
return parts;
}
static private Pattern quotePattern = Pattern.compile('(?<!")"(?!")');
/**
* Find next quote in the line
*/
private Integer findQuote(String line, Integer skip){
Matcher m = quotePattern.matcher(line);
m.region(skip, m.regionEnd());
if(!m.find())
return -1;
return m.start();
}
}
@jsenich
Copy link

jsenich commented Apr 13, 2016

This is awesome! It works way better than the code sample for CSV parsing that is available on the Developer Force site. Thanks!

@aaronpfauth
Copy link

This is great - thanks for sharing!

@pventurino
Copy link

If you change the delimiter to '[\\r\\n]{1,2}' you will be able to also parse Excel exported files as are.

@abackhouse
Copy link

Thanks for this! Awesome.

@brbjr1
Copy link

brbjr1 commented Jan 24, 2020

Thank you for sharing.

@mohsinrazasfdc
Copy link

This works great. Thanks!

@vladiasynskyi
Copy link

The solution won't work if a cell (in CSV) has a value ending with a double quote.
In the following example, Cell 2 "Test" won't be recognised correctly
Cell 1;"Cell 2 ""Test""";Cell 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment