### Using with other Codecs Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Example of fusing the CSV encoder with the JSON decoder to create a JSON to CSV conversion pipeline. ```APIDOC ### Using with other Codecs ```dart import 'dart:convert'; import 'package:csv/csv.dart'; void main() { // Create a pipeline: JSON -> CSV final csv_ = csv.asCodec(); // JSON array of arrays to CSV final jsonToCSV = json.decoder.fuse(csv_.encoder); final jsonInput = '[[["A","B"],["1","2"]]]'; // Note: This is simplified; json.decoder returns Map/List, not List } ``` ``` -------------------------------- ### Example Usage of CsvEncoder Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-encoder.md Demonstrates how to create a CsvEncoder with custom delimiters and quoting, and then use it to convert a list of rows into a CSV string. ```dart import 'package:csv/csv.dart'; void main() { final encoder = CsvEncoder( fieldDelimiter: ';', lineDelimiter: '\n', quoteMode: QuoteMode.always, ); final rows = [ ['Name', 'Age'], ['Alice', 30], ['Bob', 25], ]; final csv = encoder.convert(rows); print(csv); // "Name";"Age" // "Alice";"30" // "Bob";"25" } ``` -------------------------------- ### Install CSV Package Source: https://github.com/close2/csv/blob/master/README.md Add the CSV package to your pubspec.yaml file to include it in your project dependencies. ```yaml dependencies: csv: ^8.0.0 ``` -------------------------------- ### Decoder Usage Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Example of using the CSV decoder to convert a CSV string into a list of lists. ```APIDOC ### Decoder ```dart import 'package:csv/csv.dart'; void main() { final codec = csv.asCodec(); // Use as converter final rows = codec.decoder.convert('A,B\n1,2'); print(rows); // [['A', 'B'], ['1', '2']] // Use with fuse final fused = codec.decoder.fuse(someOtherConverter); } ``` ``` -------------------------------- ### Debugging CSV Codec Behavior Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md This example demonstrates how to use the `csv.asCodec` to create a codec that decodes a stream of CSV data into batches. It configures a maximum of 2 rows per batch and prints each received batch. ```dart import 'dart:async'; import 'package:csv/csv.dart'; void main() { final codec = csv.asCodec(maxRowsPerBatch: 2); final stream = Stream.fromIterable([ 'A,B\n', '1,2\n', '3,4\n', ]) .transform(utf8.decoder) .transform(codec.decoder); stream.listen( (batch) { print('Received batch with ${batch.length} rows:'); for (final row in batch) { print(' $row'); } }, onError: (e) => print('Error: $e'), onDone: () => print('Done'), ); } ``` -------------------------------- ### Encoder Usage Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Example of using the CSV encoder to convert a list of lists into a CSV string. ```APIDOC ### Encoder ```dart import 'package:csv/csv.dart'; void main() { final codec = csv.asCodec(); // Use as converter final csvString = codec.encoder.convert([['A', 'B'], ['1', '2']]); print(csvString); // Use with fuse final fused = someConverter.fuse(codec.encoder); } ``` ``` -------------------------------- ### Basic Field Transformation in CSV Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-decoder.md Applies a transformation to all fields in a CSV. This example trims whitespace from all string values. ```dart import 'package:csv/csv.dart'; void main() { final decoder = CsvDecoder( fieldTransform: (value, index, header) { // Trim all values if (value is String) return value.trim(); return value; }, ); final csv = 'Name, Age\n Alice , 30'; final rows = decoder.convert(csv); print(rows[1][0]); // 'Alice' (trimmed) } ``` -------------------------------- ### CSV Delimiter Auto-Detection Examples Source: https://github.com/close2/csv/blob/master/_autodocs/special-features.md Demonstrates how the CSV codec automatically detects common delimiters like comma, semicolon, tab, and pipe. Auto-detection is enabled by default. ```dart import 'package:csv/csv.dart'; void main() { final codec = Csv(); // autoDetect: true by default // Comma-delimited (most common) print(codec.decode('A,B,C\n1,2,3')); // Correctly detects: ',' // Semicolon-delimited (European CSV) print(codec.decode('A;B;C\n1;2;3')); // Correctly detects: ';' // Tab-delimited print(codec.decode('A\tB\tC\n1\t2\t3')); // Correctly detects: '\t' // Pipe-delimited print(codec.decode('A|B|C\n1|2|3')); // Correctly detects: '|' } ``` -------------------------------- ### Example Usage of QuoteMode with CsvEncoder Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Demonstrates how to use different QuoteMode values (necessary, always, strings) when creating a CsvEncoder and converting rows to CSV format. Each mode affects how fields are quoted in the output. ```dart import 'package:csv/csv.dart'; void main() { final necessaryEncoder = CsvEncoder(quoteMode: QuoteMode.necessary); final alwaysEncoder = CsvEncoder(quoteMode: QuoteMode.always); final stringsEncoder = CsvEncoder(quoteMode: QuoteMode.strings); final rows = [ ['Name', 'Age', 'Score'], ['Alice', 30, 95.5], ]; print('Necessary:'); print(necessaryEncoder.convert(rows)); // Output: // Name,Age,Score // Alice,30,95.5 print('Always:'); print(alwaysEncoder.convert(rows)); // Output: // "Name","Age","Score" // "Alice","30","95.5" print('Strings:'); print(stringsEncoder.convert(rows)); // Output: // "Name","Age","Score" // "Alice",30,95.5 } ``` -------------------------------- ### Fuse CSV Codec with Custom Converters Source: https://github.com/close2/csv/blob/master/_autodocs/advanced-usage.md Combine the CSV codec with other converters using `asCodec()` and `fuse()` to create complex data processing pipelines. This example demonstrates fusing CSV decoding and encoding with a custom field quoting logic. ```dart import 'dart:convert'; import 'package:csv/csv.dart'; class FieldQuoteConverter extends Converter>, List>> { @override List> convert(List> input) { return input.map((row) => row.map((field) { if (field is String && field.contains(',')) { return '"$field"'; } return field; }).toList()).toList(); } } void main() { final codec = csv.asCodec(); final processor = FieldQuoteConverter(); // Fuse decoder -> processor -> encoder final pipeline = codec.decoder.fuse(processor).fuse(codec.encoder); final input = 'A,B\n"Value, with comma",Normal'; final output = pipeline.convert(input); print(output); } ``` -------------------------------- ### Fuse CSV Codec with Custom Converter Source: https://github.com/close2/csv/blob/master/README.md Create a `dart:convert` `Codec` from the CSV codec using `asCodec()` and then use `.fuse()` to combine it with other converters for complex data transformations. This example adds a 'Processed' column to each row. ```dart import 'dart:convert'; import 'package:csv/csv'; // A simple converter that adds a column to every row. class AddColumnConverter extends Converter>, List>> { @override List> convert(List> input) { return input.map((row) => [...row, 'Processed']).toList(); } } void main() { final processor = AddColumnConverter(); // Use asCodec() to get a dart:convert Codec, then fuse. final codec = csv.asCodec(); final sanitizingCodec = codec.decoder.fuse(processor).fuse(codec.encoder); final inputCsv = 'Name,Age\nAlice,30'; final outputCsv = sanitizingCodec.convert(inputCsv); print(outputCsv); // Output: // Name,Age,Processed // Alice,30,Processed } ``` -------------------------------- ### Obtaining CSV Converters via asCodec() Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Shows how to get Converter types for decoding and encoding CSV data by calling asCodec() on the CSV codec. The decoder obtained this way supports fuse(). ```dart import 'dart:convert'; import 'package:csv/csv.dart'; void main() { // Get Codec from asCodec() final codec = csv.asCodec(); // Now decoder is a Converter with fuse() support final fusedDecoder = codec.decoder.fuse(someOtherConverter); } ``` -------------------------------- ### Chunked CSV Conversion with a Custom Sink Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-decoder.md Utilize `startChunkedConversion` to process CSV data in chunks, writing decoded rows to a provided `Sink`. This is useful for handling large CSV files or data arriving in segments. The example demonstrates a custom `RowSink` to collect the decoded rows. ```dart import 'package:csv/csv.dart'; class RowSink implements Sink> { List> rows = []; @override void add(List row) => rows.add(row); @override void close() {} } void main() { final decoder = CsvDecoder(); final rowSink = RowSink(); final sink = decoder.startChunkedConversion(rowSink); sink.add('Name,Age\n'); sink.add('Alice,30\n'); sink.close(); print(rowSink.rows); // [['Name', 'Age'], ['Alice', '30']] } ``` -------------------------------- ### Use Default CSV Instance Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md Demonstrates how to use the default global `Csv` instance for encoding and decoding CSV data with standard settings. ```dart import 'package:csv/csv.dart'; void main() { // Use the default CSV instance final encoded = csv.encode([['a', 'b'], ['c', 'd']]); final decoded = csv.decode(encoded); } ``` -------------------------------- ### Column-Index Based Transform Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Example of using a FieldTransform with CsvEncoder to transform a field based on its column index. This example converts the second column's string values to uppercase. ```dart import 'package:csv/csv.dart'; void main() { final encoder = CsvEncoder( fieldTransform: (field, index, header) { // Only transform column 1 (second column) if (index == 1) { return (field as String).toUpperCase(); } return field; }, ); final rows = [ ['first', 'second', 'third'], ['a', 'b', 'c'], ]; final csv = encoder.convert(rows); print(csv); // Output: // first,SECOND,third // a,B,c } ``` -------------------------------- ### startChunkedConversion() Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-decoder.md Creates a sink for chunked CSV string processing, writing decoded rows to a provided sink. ```APIDOC ## startChunkedConversion() Creates a chunked conversion sink that writes decoded rows into the provided sink. This method is used internally by `bind()` for stream transformation. Each row added to the sink is a single `List`. ### Method ```dart StringConversionSink startChunkedConversion(Sink> sink) ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **sink** (Sink>) - Required - The sink to write decoded rows to. ### Returns A `StringConversionSink` that accepts CSV string chunks. ### Example ```dart import 'package:csv/csv'; class RowSink implements Sink> { List> rows = []; @override void add(List row) => rows.add(row); @override void close() {} } void main() { final decoder = CsvDecoder(); final rowSink = RowSink(); final sink = decoder.startChunkedConversion(rowSink); sink.add('Name,Age\n'); sink.add('Alice,30\n'); sink.close(); print(rowSink.rows); // [['Name', 'Age'], ['Alice', '30']] } ``` ``` -------------------------------- ### Migrating CSV Decoding from v7 to v8 Source: https://github.com/close2/csv/blob/master/_autodocs/INDEX.md Demonstrates the difference in stream transformation for CSV decoding between version 7 and version 8 of the package. Shows how to achieve the correct output structure in v8 and how to use `asCodec()` for compatibility with the `dart:convert.Codec` interface. ```dart // Old (v7) final codec = CsvCodec(); final rows = stream.transform(codec.decoder).toList(); // Result: List>> ← Extra nesting! // New (v8) final codec = Csv(); // Same functionality, better stream behavior final rows = stream.transform(csv.decoder).toList(); // Result: List> ← Correct! // If you need Codec interface final codecAdapter = csv.asCodec(); final fused = codecAdapter.decoder.fuse(someConverter); ``` -------------------------------- ### Get Decoder and Encoder Converters Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Access the decoder and encoder as `Converter` implementations from the `dart:convert` library. ```dart // Get decoder as a Converter Converter>> decoder = codec.decoder; // Get encoder as a Converter Converter>, String> encoder = codec.encoder; ``` -------------------------------- ### Csv Class Constructor Options Source: https://github.com/close2/csv/blob/master/_autodocs/configuration.md Configure CSV parsing and generation by setting options in the Csv class constructor. Options include delimiters, quoting behavior, BOM handling, header parsing, and field transformations. ```dart Csv({ String fieldDelimiter = ',', String lineDelimiter = '\r\n', String quoteCharacter = '"', String? escapeCharacter, QuoteMode quoteMode = QuoteMode.necessary, bool addBom = false, bool autoDetect = true, bool skipEmptyLines = true, bool parseHeaders = false, dynamic Function(dynamic field, int index, String? header)? encoderTransform, dynamic Function(dynamic field, int index, String? header)? decoderTransform, bool dynamicTyping = false, }) ``` -------------------------------- ### Getting Header Name by Index Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-row.md Explains how to retrieve the header name associated with a specific column index. ```APIDOC ## getHeaderName(int index) ### Description Returns the header name for a given column index. ### Method `String? getHeaderName(int index)` ### Parameters #### Path Parameters - **index** (int) - Required - The column index to look up. ### Returns The header name for the column, or null if not found. ### Request Example ```dart import 'package:csv/csv.dart'; void main() { final headerMap = {'Name': 0, 'Age': 1, 'City': 2}; final row = CsvRow(['Alice', '30', 'New York'], headerMap); print(row.getHeaderName(0)); // 'Name' print(row.getHeaderName(1)); // 'Age' print(row.getHeaderName(2)); // 'City' print(row.getHeaderName(99)); // null (out of bounds) } ``` ``` -------------------------------- ### Create Excel-Compatible CSV Instance Source: https://github.com/close2/csv/blob/master/_autodocs/configuration.md Instantiates a CSV decoder pre-configured for Excel compatibility, using a semicolon delimiter and including a UTF-8 BOM. This instance is immutable and thread-safe. ```dart final Csv excel = Csv.excel(); ``` -------------------------------- ### Transform CSV Rows Source: https://github.com/close2/csv/blob/master/_autodocs/QUICK_START.md Map over the decoded rows to transform their content, for example, converting the first column to uppercase while keeping the rest. ```dart final transformed = rows .map((row) => [row[0].toString().toUpperCase(), ...row.skip(1)]) .toList(); ``` -------------------------------- ### Csv() Constructor Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md Creates a new Csv instance with custom configuration for encoding and decoding CSV data. ```APIDOC ## Csv() ### Description Creates a new Csv instance with custom configuration. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```dart Csv({ String fieldDelimiter = ',', String lineDelimiter = '\r\n', String quoteCharacter = '"', String? escapeCharacter, QuoteMode quoteMode = QuoteMode.necessary, bool addBom = false, bool autoDetect = true, bool skipEmptyLines = true, bool parseHeaders = false, dynamic Function(dynamic field, int index, String? header)? encoderTransform, dynamic Function(dynamic field, int index, String? header)? decoderTransform, bool dynamicTyping = false, }) ``` ### Parameter Details - **fieldDelimiter** (String) - Required - The separator between fields. Can be single or multi-character. - **lineDelimiter** (String) - Required - The separator between lines. - **quoteCharacter** (String) - Required - The character used for quoting fields. Must be single character. - **escapeCharacter** (String?) - Optional - The character used for escaping quotes inside quoted fields. Must be single character if provided. Defaults to quoteCharacter. - **quoteMode** (QuoteMode) - Required - Defines when fields should be quoted. - **addBom** (bool) - Required - Whether to add UTF-8 BOM when encoding (useful for Excel). - **autoDetect** (bool) - Required - Whether to auto-detect the delimiter when decoding. - **skipEmptyLines** (bool) - Required - Whether to skip empty lines during decoding. - **parseHeaders** (bool) - Required - Whether to treat the first row as headers and return CsvRow objects. - **encoderTransform** (Function?) - Optional - Transform function applied to fields before encoding. Receives (field, index, header). - **decoderTransform** (Function?) - Optional - Transform function applied to fields after decoding. Receives (field, index, header). - **dynamicTyping** (bool) - Required - Whether to automatically parse numbers and booleans instead of keeping all values as strings. ### Returns A new Csv instance. ### Example ```dart import 'package:csv/csv.dart'; // Create custom CSV codec with semicolon delimiter final customCsv = Csv( fieldDelimiter: ';', lineDelimiter: '\n', dynamicTyping: true, ); final data = [ ['Name', 'Age', 'Active'], ['Alice', '30', 'true'], ['Bob', '25', 'false'], ]; final encoded = customCsv.encode(data); print(encoded); // Output: Name;Age;Active\nAlice;30;true\nBob;25;false final decoded = customCsv.decode(encoded); print(decoded[1][1].runtimeType); // int print(decoded[1][2].runtimeType); // bool ``` ``` -------------------------------- ### Get CsvRow Length Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-row.md Shows how to retrieve the number of fields in a CsvRow instance using the 'length' property. This property is inherited from ListBase. ```dart import 'package:csv/csv.dart'; void main() { final headerMap = {'Name': 0, 'Age': 1}; final row = CsvRow(['Alice', '30'], headerMap); print(row.length); // 2 } ``` -------------------------------- ### Basic CSV Encoding and Decoding Source: https://github.com/close2/csv/blob/master/README.md Demonstrates the fundamental usage of the CSV package for encoding Dart data structures into CSV strings and decoding CSV strings back into Dart lists. ```dart import 'package:csv/csv.dart'; void main() { final data = [ ['Name', 'Age', 'City'], ['Alice', 30, 'New York'], ['Bob', 25, 'London'], ]; // Encode final String csvString = csv.encode(data); print(csvString); // Decode final List> decodedData = csv.decode(csvString); print(decodedData); } ``` -------------------------------- ### Decoder Transform - Trimming Whitespace Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Example of using a FieldTransform with CsvDecoder to trim whitespace from string fields. Ensure the field is a string before trimming. ```dart import 'package:csv/csv.dart'; void main() { final decoder = CsvDecoder( fieldTransform: (value, index, header) { if (value is String) return value.trim(); return value; }, ); final csv = 'Name, Age\n Alice , 30'; final rows = decoder.convert(csv); print(rows[1][0]); // 'Alice' (trimmed) } ``` -------------------------------- ### Excel Compatible Csv Instance Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md Create a Csv instance pre-configured for Excel compatibility, using a semicolon as the field delimiter and including a UTF-8 BOM. ```dart Csv.excel() ``` ```dart import 'package:csv/csv.dart'; final excelCodec = Csv.excel(); final data = [ ['Nom', 'Âge', 'Ville'], ['Alice', '30', 'Paris'], ['Bob', '25', 'Lyon'], ]; final csvString = excelCodec.encode(data); // Includes UTF-8 BOM and uses ';' as delimiter ``` -------------------------------- ### Handle Misplaced Quotes in CSV Source: https://github.com/close2/csv/blob/master/_autodocs/special-features.md The library interprets quotes that do not appear at the start of a field as literal characters within the field's value. ```dart import 'package:csv/csv.dart'; void main() { final csv = 'A,B\nvalue"with"quote,normal'; final rows = csv.decode(csv); print(rows[1][0]); // 'value"with"quote' // Quotes not at field start are treated as literal } ``` -------------------------------- ### Chaining Multiple Transformers Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Demonstrates creating a data processing pipeline by chaining the CSV decoder, custom transformers, and the CSV encoder. ```APIDOC ## Complex Fusion Examples ### Chaining Multiple Transformers ```dart import 'dart:convert'; import 'package:csv/csv.dart'; class FilterConverter extends Converter>, List>> { final bool Function(List row) predicate; FilterConverter(this.predicate); @override List> convert(List> input) { return input.where(predicate).toList(); } } class TransformConverter extends Converter>, List>> { final List Function(List row) transform; TransformConverter(this.transform); @override List> convert(List> input) { return input.map(transform).toList(); } } void main() { final codec = csv.asCodec(); // Decoder -> Filter -> Transform -> Encoder final pipeline = codec.decoder .fuse(FilterConverter((row) => row.isNotEmpty && row[0] != 'skip')) .fuse(TransformConverter((row) => [row[0].toString().toUpperCase(), ...row.skip(1)])) .fuse(codec.encoder); final input = 'A,B\nskip,value\nc,d'; final output = pipeline.convert(input); print(output); // A,B // C,d } ``` ``` -------------------------------- ### Handle Nulls in CSV Encoding/Decoding Source: https://github.com/close2/csv/blob/master/_autodocs/advanced-usage.md Demonstrates encoding nulls as empty strings and decoding them back. Shows how to use a custom decoder transform to treat empty strings as null. ```dart import 'package:csv/csv.dart'; void main() { // Encoding nulls as empty strings final rows = [ ['Name', 'Middle', 'Last'], ['Alice', null, 'Smith'], [null, 'James', 'Brown'], ]; final encoded = csv.encode(rows); print(encoded); // Name,Middle,Last // Alice,,Smith // ,James,Brown // Decoding final decoded = csv.decode(encoded); print(decoded[1][1]); // '' (empty string, not null) // To treat empty strings as null, use a transform final codec = Csv( decoderTransform: (value, index, header) { if (value is String && value.isEmpty) return null; return value; }, ); final withNulls = codec.decode(encoded); print(withNulls[1][1]); // null } ``` -------------------------------- ### Transform Fields During CSV Encode Source: https://github.com/close2/csv/blob/master/_autodocs/QUICK_START.md Utilize `encoderTransform` to alter field values before encoding. This example formats a 'Price' field by prepending a dollar sign. ```dart final codec = Csv( encoderTransform: (value, index, header) { if (header == 'Price') return ' ${value}'; return value; }, ); final csv = codec.encode([['Name', 'Price'], ['Item', 99.99]]); // Name,Price // Item,$99.99 ``` -------------------------------- ### Csv.excel() Factory Constructor Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md Creates a Csv instance pre-configured for compatibility with Microsoft Excel. ```APIDOC ## Csv.excel() ### Description Creates a Csv instance configured for Excel compatibility. Uses `;` (semicolon) as the field delimiter and adds a UTF-8 BOM prefix. This is useful for CSV files that need to be opened in Microsoft Excel with proper character encoding and delimiter recognition. ### Parameters None ### Returns A new Csv instance configured for Excel. ### Example ```dart import 'package:csv/csv.dart'; final excelCodec = Csv.excel(); final data = [ ['Nom', 'Âge', 'Ville'], ['Alice', '30', 'Paris'], ['Bob', '25', 'Lyon'], ]; final csvString = excelCodec.encode(data); // Includes UTF-8 BOM and uses ';' as delimiter ``` ``` -------------------------------- ### Fuse Custom Converter with CSV Codec Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Fuse a custom converter with the CSV codec to process data before encoding or after decoding. This example adds a 'Processed' column to each row. ```dart import 'dart:convert'; import 'package:csv/csv.dart'; class AddColumnConverter extends Converter>, List>> { @override List> convert(List> input) { return input.map((row) => [...row, 'Processed']).toList(); } } void main() { final processor = AddColumnConverter(); // Use asCodec() to get a Codec, then fuse final codec = csv.asCodec(); final sanitizingCodec = codec.decoder.fuse(processor).fuse(codec.encoder); final inputCsv = 'Name,Age\nAlice,30\nBob,25'; final outputCsv = sanitizingCodec.convert(inputCsv); print(outputCsv); // Name,Age,Processed // Alice,30,Processed // Bob,25,Processed } ``` -------------------------------- ### CsvDecoder() Constructor Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-decoder.md Creates a new CsvDecoder instance with customizable parsing options. It can be configured to auto-detect delimiters, handle quote and escape characters, skip empty lines, transform fields, parse headers, and enable dynamic typing for values. ```APIDOC ## CsvDecoder() ### Description Creates a new CsvDecoder instance. ### Parameters #### Constructor Parameters - **fieldDelimiter** (String?) - Optional - The separator between fields. If null, the delimiter is auto-detected. Must be a single character or multi-character string. - **quoteCharacter** (String) - Optional - The character used for quoting fields. Must be a single character. Defaults to '"'. - **escapeCharacter** (String?) - Optional - The character used for escaping quotes inside quoted fields. Must be a single character if provided. Defaults to quoteCharacter. - **skipEmptyLines** (bool) - Optional - Whether to skip empty lines during decoding. Defaults to true. - **fieldTransform** (Function?) - Optional - Transform function applied to each field after decoding. Receives (field, index, header). Defaults to null. - **parseHeaders** (bool) - Optional - Whether to treat the first row as headers and return CsvRow objects. Defaults to false. - **dynamicTyping** (bool) - Optional - Whether to automatically parse numbers and booleans instead of keeping all values as strings. Defaults to false. ### Returns A new CsvDecoder instance. ### Throws - AssertionError if quoteCharacter is not a single character. - AssertionError if escapeCharacter is provided and is not a single character. ### Example ```dart import 'package:csv/csv.dart'; void main() { final decoder = CsvDecoder( fieldDelimiter: ';', parseHeaders: true, dynamicTyping: true, ); final csv = 'Name;Age;Active\nAlice;30;true'; final rows = decoder.convert(csv); final row = rows[0] as CsvRow; print(row['Age']); // 30 (int) print(row['Active']); // true (bool) } ``` ``` -------------------------------- ### Handle Delimiters in Quoted Fields Source: https://github.com/close2/csv/blob/master/_autodocs/special-features.md Delimiters within quoted fields are ignored by default. This example shows how commas inside quotes are treated as part of the field value. ```dart import 'package:csv/csv.dart'; void main() { final csv = 'Name,Description\nAlice,"Value with, comma"\nBob,"Another, value"'; final rows = csv.decode(csv); print(rows[1][1]); // 'Value with, comma' print(rows[2][1]); // 'Another, value' } ``` -------------------------------- ### Encode and Decode CSV Data Source: https://github.com/close2/csv/blob/master/_autodocs/00-START-HERE.md Demonstrates basic CSV encoding and decoding. Use `decodeWithHeaders` to access columns by name. ```dart import 'package:csv/csv.dart'; // Encode final csv = csv.encode([['a', 'b'], ['1', '2']]); // Decode final rows = csv.decode(csv); // With headers final rows = csv.decodeWithHeaders(csv); print(rows[0]['a']); // Access by column name ``` -------------------------------- ### Column-Specific Field Transformation in CSV Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-decoder.md Applies transformations to specific columns based on their header name. This example converts the 'Age' column to an integer and uppercases the 'City' column. ```dart import 'package:csv/csv.dart'; void main() { final decoder = CsvDecoder( fieldDelimiter: ';', parseHeaders: true, fieldTransform: (value, index, header) { // Convert 'Age' column to int if (header == 'Age') return int.tryParse(value) ?? value; // Uppercase 'City' column if (header == 'City') return (value as String).toUpperCase(); return value; }, ); final csv = 'Name;City;Age\nAlice;london;30'; final rows = decoder.convert(csv); final row = rows[0] as CsvRow; print(row['Age']); // 30 (int) print(row['City']); // LONDON } ``` -------------------------------- ### Create and Access CsvRow Data Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-row.md Demonstrates how to create a CsvRow instance and access its fields using both integer indices and string header names. Ensure you have the 'csv' package imported. ```dart import 'package:csv/csv.dart'; void main() { final headerMap = {'Name': 0, 'Age': 1, 'City': 2}; final fields = ['Alice', '30', 'New York']; final row = CsvRow(fields, headerMap); // Access by index print(row[0]); // 'Alice' // Access by header name print(row['Name']); // 'Alice' print(row['Age']); // '30' } ``` -------------------------------- ### Get Header Name by Index Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-row.md The getHeaderName() method retrieves the header name associated with a given column index. It returns null if the index is out of bounds or has no corresponding header. ```dart import 'package:csv/csv.dart'; void main() { final headerMap = {'Name': 0, 'Age': 1, 'City': 2}; final row = CsvRow(['Alice', '30', 'New York'], headerMap); print(row.getHeaderName(0)); // 'Name' print(row.getHeaderName(1)); // 'Age' print(row.getHeaderName(2)); // 'City' print(row.getHeaderName(99)); // null (out of bounds) } ``` -------------------------------- ### Create Default CSV Instance Source: https://github.com/close2/csv/blob/master/_autodocs/configuration.md Instantiates a CSV decoder with standard configuration, including a comma delimiter and CRLF line endings. This instance is immutable and thread-safe. ```dart final Csv csv = Csv(); ``` -------------------------------- ### Transform Fields During CSV Decode Source: https://github.com/close2/csv/blob/master/_autodocs/QUICK_START.md Use `decoderTransform` to modify field values based on their index or header name during decoding. This example converts 'Age' to int and 'Name' to uppercase. ```dart final codec = Csv( parseHeaders: true, decoderTransform: (value, index, header) { if (header == 'Age') return int.tryParse(value) ?? value; if (header == 'Name') return (value as String).toUpperCase(); return value; }, ); final rows = codec.decode(csvString); final row = rows[0] as CsvRow; print(row['Age']); // 30 (int) print(row['Name']); // ALICE ``` -------------------------------- ### Using CsvDecoder and CsvEncoder as Stream Transformers Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Demonstrates using CsvDecoder and CsvEncoder directly with Stream.transform(). This is possible because they extend StreamTransformerBase. ```dart import 'dart:io'; import 'dart:convert'; import 'package:csv/csv.dart'; void main() async { // Use decoder as a stream transformer final rows = await File('data.csv') .openRead() .transform(utf8.decoder) .transform(CsvDecoder()) .toList(); // rows is List>: each element is one row // Use encoder as a stream transformer final csv = Stream.fromIterable([ ['Name', 'Age'], ['Alice', 30], ]) .transform(CsvEncoder()) .join(); // csv is Stream } ``` -------------------------------- ### Encoder Transform - Formatting Values Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Example of using a FieldTransform with CsvEncoder to format specific data types or fields. Converts DateTime to ISO8601 string and prefixes a 'Price' field with a dollar sign. ```dart import 'package:csv/csv.dart'; void main() { final encoder = CsvEncoder( fieldTransform: (field, index, header) { if (field is DateTime) { return field.toIso8601String(); } if (header == 'Price') { return ' ${field}'; } return field; }, ); final rows = [ ['Name', 'Date', 'Price'], ['Alice', DateTime(2024, 1, 15), 99.99], ]; final csv = encoder.convert(rows); print(csv); // Output: // Name,Date,Price // Alice,2024-01-15T00:00:00.000Z,$99.99 } ``` -------------------------------- ### Configure CsvEncoder Source: https://github.com/close2/csv/blob/master/_autodocs/configuration.md Instantiate CsvEncoder with custom options for encoding data into CSV format. Options include field and line delimiters, quote and escape characters, quoting modes, adding a UTF-8 BOM, and custom field transformations. ```dart const CsvEncoder({ String fieldDelimiter = ',', String lineDelimiter = '\r\n', String quoteCharacter = '"', String? escapeCharacter, QuoteMode quoteMode = QuoteMode.necessary, bool addBom = false, dynamic Function(dynamic field, int index, String? header)? fieldTransform, }) ``` -------------------------------- ### Using CSV Codec with JSON Codec Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Demonstrates creating a pipeline to convert JSON data to CSV format by fusing the JSON decoder with the CSV encoder. ```dart import 'dart:convert'; import 'package:csv/csv.dart'; void main() { // Create a pipeline: JSON -> CSV final csv_ = csv.asCodec(); // JSON array of arrays to CSV final jsonToCSV = json.decoder.fuse(csv_.encoder); final jsonInput = '[[["A","B"],["1","2"]]]'; // Note: This is simplified; json.decoder returns Map/List, not List } ``` -------------------------------- ### Decoder Transform - Type Conversion Source: https://github.com/close2/csv/blob/master/_autodocs/types.md Example of using a FieldTransform with CsvDecoder to convert string fields to integers or booleans based on header names. Handles potential parsing errors by returning the original value. ```dart import 'package:csv/csv.dart'; void main() { final decoder = CsvDecoder( parseHeaders: true, fieldTransform: (value, index, header) { if (header == 'Age') return int.tryParse(value) ?? value; if (header == 'Active') { return value == 'true' ? true : value == 'false' ? false : value; } return value; }, ); final csv = 'Name;Age;Active\nAlice;30;true\nBob;25;false'; final rows = decoder.convert(csv); final row1 = rows[0] as CsvRow; print(row1['Age']); // 30 (int) print(row1['Active']); // true (bool) } ``` -------------------------------- ### Using asCodec() with Max Rows Per Batch Source: https://github.com/close2/csv/blob/master/README.md Configure the Codec adapter returned by asCodec() with a maximum number of rows per batch. This helps manage memory for large files when using Codec APIs. ```dart final codec = csv.asCodec(maxRowsPerBatch: 100); ``` -------------------------------- ### CSV Codec Fusion Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Demonstrates using `asCodec()` to obtain a `Codec` object, which can then be fused with other converters for complex conversion pipelines. ```dart import "package:csv/csv.dart"; // Good: codec fusion void goodFusion() { final codec = csv.asCodec(); // Use asCodec() here final fused = codec.decoder.fuse(someConverter); } ``` -------------------------------- ### CsvRow Constructor Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-row.md Creates a new CsvRow instance with the provided fields and header map. ```APIDOC ## CsvRow() ### Description Creates a new CsvRow instance. ### Parameters #### Path Parameters - **fields** (List) - Required - The field values for this row. - **headerMap** (Map) - Required - A map from header names to column indices. ### Request Example ```dart import 'package:csv/csv.dart'; void main() { final headerMap = {'Name': 0, 'Age': 1, 'City': 2}; final fields = ['Alice', '30', 'New York']; final row = CsvRow(fields, headerMap); // Access by index print(row[0]); // 'Alice' // Access by header name print(row['Name']); // 'Alice' print(row['Age']); // '30' } ``` ``` -------------------------------- ### asCodec() Method Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Returns a Codec>, String> adapter that wraps the CSV parsing logic. This is useful when you need to use Codec-specific APIs. ```APIDOC ## asCodec() ### Description Provides a `dart:convert` Codec adapter for CSV operations when you need Codec-specific APIs like `fuse()`. ### Method Signature ```dart Codec>, String> asCodec({int? maxRowsPerBatch}) ``` ### Parameters #### Path Parameters - **maxRowsPerBatch** (int?) - Optional - Maximum rows to emit in a single batch. If null, all rows from a chunk are emitted together. Use 1 for single-row batches. ### Returns A `Codec>, String>` adapter. ### Throws - Assertion error if `maxRowsPerBatch` is provided but not positive. ### Stream Behavior When the codec adapter's decoder is used as a stream transformer, it emits `List>` (a batch of rows per event), unlike the direct decoder which emits `List` (one row per event). This can lead to an extra layer of list nesting in the final output. ### Example ```dart import 'dart:convert'; import 'dart:io'; import 'package:csv/csv.dart'; void main() async { // ✓ Correct: use decoder directly for streams final rows1 = await File('data.csv') .openRead() .transform(utf8.decoder) .transform(csv.decoder) .toList(); // rows1 is List>: each element is one row // ✗ Not recommended: use asCodec() only for codec operations final rows2 = await File('data.csv') .openRead() .transform(utf8.decoder) .transform(csv.asCodec().decoder) .toList(); // rows2 is List>>: extra nesting! } ``` ``` -------------------------------- ### Stream Batching Behavior Example Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/codec-adapter.md Demonstrates how `maxRowsPerBatch` affects stream output. Rows are accumulated and emitted when the batch size is reached or when the input chunk boundary is met. The final flush also emits any remaining rows. ```dart import 'dart:async'; import 'package:csv/csv.dart'; void main() { final codec = csv.asCodec(maxRowsPerBatch: 2); // Simulating chunked CSV input final stream = Stream.fromIterable([ 'A,B\n', '1,2\n3,4\n', '5,6', ]) .transform(utf8.decoder) .transform(codec.decoder); // Will emit batches of up to 2 rows each stream.listen((batch) { print('Batch: $batch'); // Batch: [['A', 'B']] // Batch: [['1', '2'], ['3', '4']] // Batch: [['5', '6']] }); } ``` -------------------------------- ### Conditional CSV Row Processing and Writing Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/streaming.md Filter CSV rows based on a condition and write only the matching rows to a new file. This example uses the `where` stream transformer to filter rows where the 'age' column is greater than 25. ```dart import 'dart:convert'; import 'dart:io'; import 'package:csv/csv.dart'; void main() async { final input = File('input.csv'); final output = File('output.csv'); final codec = Csv(parseHeaders: true); // Only write rows where a condition is met await input .openRead() .transform(utf8.decoder) .transform(codec.decoder) .where((row) { final csvRow = row as CsvRow; // Only include rows where age > 25 final age = int.tryParse(csvRow['age'].toString()) ?? 0; return age > 25; }) .transform(codec.encoder) .transform(utf8.encoder) .pipe(output.openWrite()); } ``` -------------------------------- ### Custom CSV Configuration Source: https://github.com/close2/csv/blob/master/_autodocs/INDEX.md Create a custom CSV codec with specific delimiters, dynamic typing, and header parsing enabled. Useful for non-standard CSV formats. ```dart import 'package:csv/csv.dart'; final codec = Csv( fieldDelimiter: ';', dynamicTyping: true, parseHeaders: true, ); final rows = codec.decode(csvString); ``` -------------------------------- ### CSV Stream Error Handling Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/streaming.md Implement robust error handling for CSV stream processing. This example shows how to use the `onError` callback in `listen` to catch and log errors during file parsing, along with stack traces. ```dart import 'dart:convert'; import 'dart:io'; import 'package:csv/csv.dart'; void main() async { final file = File('data.csv'); await file .openRead() .transform(utf8.decoder) .transform(csv.decoder) .listen( (row) => print('Row: $row'), onError: (error, stackTrace) { print('Error processing CSV: $error'); print(stackTrace); }, onDone: () => print('CSV processing complete'), ); } ``` -------------------------------- ### Csv Class Constructors Source: https://github.com/close2/csv/blob/master/_autodocs/INDEX.md Provides constructors for creating custom CSV codecs or Excel-compatible codecs. ```APIDOC ## `Csv()` ### Description Creates a custom CSV codec with default settings. ### Signature `Csv()` ## `Csv.excel()` ### Description Creates an Excel-compatible CSV codec, which may have different quoting or delimiter rules. ### Signature `Csv.excel()` ``` -------------------------------- ### Excel-Compatible CSV Instance Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md A CSV instance configured for Excel compatibility, using a semicolon delimiter and UTF-8 BOM. This is useful when generating CSV files intended for direct import into Microsoft Excel. ```APIDOC ### excel ```dart final Csv excel = Csv.excel() ``` A CSV instance configured for Excel compatibility (semicolon delimiter, UTF-8 BOM). **Location:** `lib/csv.dart` **Example:** ```dart import 'package:csv/csv.dart'; void main() { // Use the Excel-compatible CSV instance final data = [ ['Nom', 'Âge'], ['Alice', '30'], ]; final excelCsv = excel.encode(data); // Includes BOM and uses ';' as delimiter } ``` ``` -------------------------------- ### Custom Csv Instance Creation Source: https://github.com/close2/csv/blob/master/_autodocs/api-reference/csv-class.md Create a custom CSV codec by specifying field and line delimiters, quote character, escape character, quote mode, BOM addition, auto-detection, empty line skipping, header parsing, encoder/decoder transforms, and dynamic typing. ```dart Csv({ String fieldDelimiter = ',', String lineDelimiter = '\r\n', String quoteCharacter = '"', String? escapeCharacter, QuoteMode quoteMode = QuoteMode.necessary, bool addBom = false, bool autoDetect = true, bool skipEmptyLines = true, bool parseHeaders = false, dynamic Function(dynamic field, int index, String? header)? encoderTransform, dynamic Function(dynamic field, int index, String? header)? decoderTransform, bool dynamicTyping = false, }) ``` ```dart import 'package:csv/csv.dart'; // Create custom CSV codec with semicolon delimiter final customCsv = Csv( fieldDelimiter: ';', lineDelimiter: '\n', dynamicTyping: true, ); final data = [ ['Name', 'Age', 'Active'], ['Alice', '30', 'true'], ['Bob', '25', 'false'], ]; final encoded = customCsv.encode(data); print(encoded); // Output: Name;Age;Active\nAlice;30;true\nBob;25;false final decoded = customCsv.decode(encoded); print(decoded[1][1].runtimeType); // int print(decoded[1][2].runtimeType); // bool ```