jsonToCsv function

Future jsonToCsv(
  1. dynamic jsonData,
  2. String fileName
)

Converts JSON data to a CSV file and downloads it.

This function takes JSON data in the form of a JSON string or a Map/List of Maps and converts it to a CSV file. The resulting CSV file is then downloaded. It also handles the replacement of commas in values with semicolons to prevent CSV formatting issues.

Parameters:

  • jsonData: JSON data to be converted to CSV (can be a JSON string, Map, or List of Maps).
  • fileName: The name of the CSV file to be generated.

Implementation

Future jsonToCsv(
  dynamic jsonData,
  String fileName,
) async {
  if (jsonData is String) {
    jsonData = jsonDecode(jsonData);
  } else if (jsonData is! Map<String, dynamic> &&
      jsonData is! List<Map<String, dynamic>>) {
    throw ArgumentError(
        'Invalid JSON data. It should be a JSON string, Map, or List of Maps.');
  }

  List<Map<String, dynamic>> jsonList;

  if (jsonData is Map<String, dynamic>) {
    // If jsonData is a single JSON object, wrap it in a list
    jsonList = [jsonData];
  } else {
    jsonList = jsonData as List<Map<String, dynamic>>;
  }

  if (jsonList.isEmpty) {
    throw ArgumentError('JSON data is empty.');
  }

  // Extract the headers from the first object
  List<String> headers = jsonList[0].keys.toList();

  // Create a string to hold the CSV data
  String dataString = headers.join(",") + "\n";

  for (Map<String, dynamic> json in jsonList) {
    List<String> values = [];
    for (String header in headers) {
      // Replace commas in values with semicolons to prevent CSV formatting issues
      values.add(json[header].toString().replaceAll(',', ';'));
    }
    dataString += values.join(",") + "\n";
  }

  // Generate a formatted timestamp for the filename
  final creationTime = DateFormat('dd_MM_yyyy_HH:mm:ss').format(DateTime.now());

  // Convert the CSV string to a list of bytes (Uint8List)
  Uint8List csvBytes = Uint8List.fromList(dataString.codeUnits);

  // Convert the Uint8List to a Stream<int>
  Stream<int> csvStream = Stream.fromIterable(csvBytes.map((byte) => byte));

  // Download the CSV file with a unique filename
  await download(csvStream, '$fileName-$creationTime.csv');
}