Dynamically display JSON data in data table layout in flutter

3,781

Solution 1

Step 1:

[
  {
    "DayEnd": [
      {
        "ColumnWidths": "40´168´96´96´108´156",
        "Headers": "SL.>´Customer< ´Balance Qty>´Amount>´Oldest / Recent ",
        "FieldSeparator": "´",
        "DataList": [
          {
            "Data": "1. ´ABD ´14 / 14.60´11,090´313 / 313",
            "NextLevelZoomData": [
              {
                "Element": "eg7P27fbW/GmCr"
              },
              {
                "Element": "AAA=="
              }
            ],
            "NextLevelZoomType": 2
          }
        ]
      }
    ]
  }
]

Step 2:

 class TableModel {
  TableModel(this.headerData, this.rowData);
  List<String> headerData;
  List<List<String>> rowData;

  factory TableModel.fromJson(Map<String, dynamic> json) {
    return TableModel(
      json['DayEnd'][0]["Headers"].split('´').toList(),
      buildRowData(json),
    );
  }
}

List<List<String>> buildRowData(Map<String, dynamic> json){
  List<List<String>> rowDataCollection = [];
  json['DayEnd'][0]["DataList"].forEach((rows){
    rowDataCollection.add(rows['Data'].split('´').toList());
  });

  return rowDataCollection;
}

Step 3:

Future<void> generateList() async {
    String responseBody = await rootBundle.loadString("assets/data.json");
    var list = await json.decode(responseBody).cast<Map<String, dynamic>>();
    return await list
        .map<TableModel>((json) => TableModel.fromJson(json))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
            appBar: AppBar(
              title: Text('DataTable'),
            ),
            body: FutureBuilder(
              future: generateList(),
              builder: (context, snapShot) {
                if (snapShot.data == null ||
                    snapShot.connectionState == ConnectionState.waiting ||
                    snapShot.hasError ||
                    snapShot.data.length == 0) {
                  return Container(
                    child: Center(child: CircularProgressIndicator()),
                  );
                } else {
                  return ListView.builder(
                      shrinkWrap: true,
                      scrollDirection: Axis.vertical,
                      itemCount: snapShot.data.length,
                      itemBuilder: (BuildContext context, int index) {
                        final TableModel table = snapShot.data[index];
                        return SingleChildScrollView(
                          scrollDirection: Axis.horizontal,
                          child: DataTable(
                            columns: table.headerData.map<DataColumn>((e) {
                              var columnName = e;
                              TextAlign align;
                              if (columnName.contains('<')) {
                                align = TextAlign.start;
                                columnName = columnName.replaceAll('<', '');
                              } else if (columnName.contains('>')) {
                                align = TextAlign.end;
                                columnName = columnName.replaceAll('>', '');
                              } else {
                                align = TextAlign.center;
                              }

                              return DataColumn(
                                  label: Text(
                                columnName,
                                textAlign: align,
                              ));
                            }).toList(),
                            rows: table.rowData.map<DataRow>((e) {
                              return DataRow(
                                  cells: e
                                      .map<DataCell>((e) => DataCell(Text(e)))
                                      .toList());
                            }).toList(),
                          ),
                        );
                      });
                }
              },
            )));
  }

DataTable

Solution 2

use createTable() & give it list & the object must have .tojson() method

import 'package:flutter/material.dart';

// This class takes any list that its elements have .toJson method and return every list element as a table row
class TableController {
  static Widget createTable(List list) {
    List<TableRow> rows = [];
    rows.add(_createTableHeader(list[0].toJson().keys));
    for (var item in list) {
      rows.add(TableRow(
        children: _createTableBody(item.toJson().values),
      ));
    }
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Table(border: TableBorder.all(), children: rows),
    );
  }

  static TableRow _createTableHeader(Iterable<String> keys) {
    List<Widget> elements = [];
    for (String key in keys) {
      elements.add(Padding(
        padding: const EdgeInsets.all(4.0),
        child: Text(key.toString(), overflow: TextOverflow.ellipsis),
      ));
    }
    return TableRow(
      children: elements,
    );
  }

  static List<Widget> _createTableBody(Iterable values) {
    List<Widget> elements = [];
    for (var value in values) {
      elements.add(Padding(
        padding: const EdgeInsets.all(4.0),
        child: Text(value.toString(), overflow: TextOverflow.ellipsis),
      ));
    }
    return elements;
  }
}

use it like this:

class Employee {
      Employee({
        this.id,
        this.name,
        this.email,
      });
    
      int id;
      String name;
      String email;
    
      Map<String, dynamic> toJson() => {
            "id": id,
            "name": name,
            "email": email,
          };
    }
    
    final Employee emp = Employee(id: 1, name: 'name 1');
    final Employee emp1 = Employee(id: 2, name: 'name 2');
    final Employee emp2 = Employee(id: 3, name: 'name 3');
    final Employee emp3 = Employee(id: 4, name: 'name 4');
    final List<Employee> emps = [emp, emp2, emp1];

class TablePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(child: TableController.createTable(emps)),
        );
      }
    }

output: enter image description here

Share:
3,781
Android_id
Author by

Android_id

Learning

Updated on December 27, 2022

Comments

  • Android_id
    Android_id over 1 year

    I am Creating a Dynamic data table view in flutter , where the column headers and the row values are added dynamically. The data is a Json response,the header is a string array and the data to be displayed in row is also a string array .The goal is to display the data in the table view without any hardcoded values. This is how I have tried is to display the data.

                         return ListView.builder(
                             shrinkWrap: true,
                             scrollDirection: Axis.vertical,
                             itemCount: snapshot.data.dataList.length,
                             itemBuilder: (BuildContext context, int index){
                               return SingleChildScrollView(
                                 child: DataTable(
                                   columns: (snapshot.data.headerList[index] as List).map((item) =>
                                   DataColumn(
                                       label:(
                                           List.generate(item.length,(index){
                                             return Text(item[index].toString());
                                           })
                                       )
                                   )).toList(),
                                   rows: (snapshot.data.dataList[index].dataList as List).map((item) =>
                                   
                                   DataRow(
                                     
                                       cells:<DataCell>[
                                         DataCell(
                                             List.generate(item.length,(index){
                                               return Text(item[index].toString());
                                             })
                                         )
                                        ])).toList(),
                                 ),
    

    This is the JSON response

     "DayEnd": {
            "ColumnWidths": "40´168´96´96´108´156",
            "Headers": "SL.>´Customer< ´Balance Qty>´Amount>´Oldest / Recent ",
            "FieldSeparator": "´",
            "DataList": [
                {
                    "Data": "1. ´ABD ´14 / 14.60´11,090´313 / 313",
                    "NextLevelZoomData": [
                        {
                            "Element": "eg7P27fbW/GmCr"
                        },
                        {
                            "Element": "AAA=="
                        }
                    ],
                    "NextLevelZoomType": 2
                },
                {
                    "Data": "2. ´LATA´16´7,921´20 / 9",
                    "NextLevelZoomData": [
                        {
                            "Element": "MT63z0m7piukmtJZqdZ"
                        },
                        {
                            "Element": "QT/2zE/AAA="
                        }
                    ],
                    "NextLevelZoomType": 2
                },
                {
                    "Data": "3. ´ANAND´11´915´426 / 426",
                    "NextLevelZoomData": [
                        {
                            "Element": "AAA="
                        }
                    ],
                    "NextLevelZoomType": 2
                },
                {
                    "Data": "4. ´Asts´1´1,010´27 / 27",
                    "NextLevelZoomData": [
                        {
                            "Element": "w/VbTHwKgQAAA=="
                        }
                    ],
                    "NextLevelZoomType": 2
                },
                }
    

    The above response gives a string data Headers which is separated by a special character "`",the each character has to be displayed in a each column header so which is converted to an array. Similarly the data as well . The column width that has to be maintained for each data is mentioned in columnWidth Similarly the alignment of the data like if "SL.>" then ">" it has to be right aligned.

    I am not sure if this is the right approach to get it, This gives an error

    The argument type 'List<Text>' can't be assigned to the parameter type 'Widget'.
    

    Any idea to approach in a better way will be much appreciated.