Skip to content

Instantly share code, notes, and snippets.

@mhamzas
Forked from f1code/gist:858086
Created May 28, 2021 12:09
Show Gist options
  • Select an option

  • Save mhamzas/039f865e242e7f20b1947e88a32fe7be to your computer and use it in GitHub Desktop.

Select an option

Save mhamzas/039f865e242e7f20b1947e88a32fe7be 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();
}
}
@mhamzas

mhamzas commented Feb 18, 2025

Copy link
Copy Markdown
Author

Doesn't work properly. Multiline cells are not handled correctly. You cannot just use split. Also, correct line delimiter is CRLF (\r\n), not LF (\n).

Hi TrangOul, thanks for highlighting the issues.
This gist is a fork of https://gist.github.com/nicocrm/858086, where you can find appropriate comments. It's been a while since I worked on such a scenario, so I cannot offer any workarounds at the moment.

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