Changes from version 2 to 3:
parseNumbershas been renamed to
FirstOccurenceSettingsDetectorhas been renamed to
- Speed improvements.
A dart csv to list codec / converter.
If you have a
String of all rows with RFC conform separators and delimiters, simply convert them with:
List<List<dynamic>> rowsAsListOfValues = const CsvToListConverter().convert(yourString);
To convert to a Csv string your values must be in a
List<List<dynamic>> representing a List of Rows where every Row
is a List of values. You can then convert with:
String csv = const ListToCsvConverter().convert(yourListOfLists);
This converter is implemented as codec and may be used as transformer for streams:
final csvCodec = new CsvCodec(); final stream = new Stream.fromIterable([['a', 'b'], [1, 2]]); final csvRowStream = stream.transform(csvCodec.encoder);
Or the decoder side:
final input = new File('a/csv/file.txt').openRead(); final fields = await input.transform(UTF8.decoder).transform(csvCodec.decoder).toList();
The converter is highly customizable and even allows multiple characters as delimiters or separators.
Every csv row is converted to a list of values. Unquoted strings looking like
numbers (integers and doubles) are by default converted to
The input must be a
Lists. Every inner list is converted to one
output csv row. The string representation of values is obtained by calling
This converter follows the rules of rfc4180.
This means that text fields containing any delimiter or an eol are quoted.
The default configuration is:
- , as field separator
- " as text delimiter and
- \r\n as eol.
This parser will accept eol and text-delimiters inside unquoted text and not throw an error.
In addition this converter supports multiple characters for all delimiters
and eol. Also the start text delimiter and end text delimiter may be
different. This means the following text can be parsed:
And (if configured correctly) will return
['abc«d', 'xy»z', 123]
If the default values are fine, simply instantiate
final res = const ListToCsvConverter().convert([[',b', 3.1, 42], ['n\n']]); assert(res == '",b",3.1,42\r\n"n\n"');
There are 2 interesting things to note:
- Not all rows have to be the same length.
The default eol is
'\n'is also quoted. The appearance of only one character is enough for the string to be quoted.
The converter takes the following configurations either in the constructor or
fieldDelimiter: the separator between fields. By default
','but another common value is
textDelimiter: the quotation string. By default
textEndDelimiter: the end quotation string. By default equals
textDelimiter. The string used to end a quoted string.
eol: The new line string. By default
'\r\n'. Another common value:
All configuration values may be multiple characters!:
const conv = const ListToCsvConverter(fieldDelimiter: '|*|', textDelimiter: '<<', textEndDelimiter: '>>', eol: '**\n'); final res = conv.convert([['a','>'], ['<<', '>>'], [1, 2]]); assert(res == 'a|*|<<>>>**\n<<<<>>|*|<<>>>>>>**\n1|*|2'); final res2 = const ListToCsvConverter() .convert([['a','>'], ['<<', '>>'], [1, 2]], fieldDelimiter: '|*|', textDelimiter: '<<', textEndDelimiter: '>>', eol: '**\n'); assert(res == res2);
`'<<' is quoted as well, but because it is "only" a start text delimiter it is not doubled. (See rule 7. below).
'>>'is quoted. Only the end-quote string is doubled!
If the default values are fine, simply instantiate
final res = const CsvToListConverter().convert('",b",3.1,42\r\n"n\n"'); assert(res.toString() == [[',b', 3.1, 42], ['n\n']].toString());
Again please note that depending on the input not all rows have the same number of values.
CsvToListConverter takes the same arguments as the
shouldParseNumbers: by default true. If you want the output to be
Strings only set this to false.
allowInvalid: by default true. The converter will by default never throw an exception. Even if
textDelimiter,... don't make sense or the csv-String is invalid. This may for instance happen if the csv-String ends with a quoted String without the end-quote (
csvSettingsDetector: must be an object which extends from
CsvSettingsDetector. There is a simple implementation which simply uses the first occurrence of a list of possible values as value.
var d = new FirstOccurrenceSettingsDetector(eols: ['\r\n', '\n'], textDelimiters: ['"', "'"]); new CsvToListConverter(csvSettingsDetector: d);
In this case
eol will either be
'\n' depending on which of
those 2 comes first in the csv string. Note that the
FirstOccurrenceSettingsDetector doesn't parse the csv string! For instance
if eol should be
'\r\n' but there is a field with a correctly quoted
in the first row,
'\n' is used instead.
To check your configuration values there is
verifyCurrentSettings. Both return an empty list if all settings are valid,
or a list of errors. If the optional
throwError is true an error is thrown in
case the settings are invalid.
All settings must be set, i.e. not be null, and delimiters, separators and eols must be distinguishable, i.e. they may not be the start of another settings.
CSV rules -- copied from RFC4180 Chapter 2
Ad rule 3: removed as it is not relevant for this converter.
Each record is located on a separate line, delimited by a line break (CRLF). For example: aaa,bbb,ccc CRLF zzz,yyy,xxx CRLF
The last record in the file may or may not have an ending line break. For example:
Within the header and each record, there may be one or more fields, separated by commas. Each line should contain the same number of fields throughout the file. Spaces are considered part of a field and should not be ignored. The last field in the record must not be followed by a comma. For example:
Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes at all). If fields are not enclosed with double quotes, then double quotes may not appear inside the fields. For example:
"aaa","bbb","ccc" CRLF zzz,yyy,xxx
Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes. For example:
"aaa","b CRLF bb","ccc" CRLF zzz,yyy,xxx
If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote. For example: