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();
}
}
@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