如何使用JSON数据创建动态表格?

3

我有一个HTML表格,使用JSON数据的帮助来创建它,我仅使用JavaScript创建我的表格,并且我的表格是动态的。

我有一个JSON数组,其中包含几个对象,这些对象具有数据。

从这个JSON中,我正在尝试制作一个HTML表格。

  • 我已经成功创建了标题,但在创建正文部分时遇到问题
  • 我正在尝试创建这种类型的表格:

    table

  • 平均值就像所有取消账单的总和除以出口数量一样,这就是为什么我正在计算出口的长度并将其存储在全局变量中

  • 由于我的代码有点长,我已经注释了我正在做什么以及遇到什么问题的所有行
  • 在正文部分中,我不知道如何根据出口填充已取消账单数据,同样适用于重复账单

这是我目前所做的:

var outletCount = 0; //global variable to get the no of outlets
var data = [{
    "outlet": "JAYANAGAR",
    "cancelled": 126544,
    "duplicate": 1
  },
  {
    "outlet": "MALLESHWARAM",
    "cancelled": 31826,
    "duplicate": 31
  },
  {
    "outlet": "KOLAR",
    "cancelled": 10374,
    "duplicate": 10
  }
];

let formatData = function(data) { //outlets is unique thats why formating it to loop forward in my code
  let outlets = [];
  data.forEach(element => {
    if (outlets.indexOf(element.outlet) == -1) {
      outlets.push(element.outlet);
    }
  });
  outletCount = outlets.length //calculating outlet count

  return {
    data: data,
    outlets: outlets,

  };
};

let renderTable = function(data) {
  outlets = data.outlets;
  data = data.data;
  let tbl = document.getElementById("tblOlSalesSummary");
  let table = document.createElement("table");
  let thead = document.createElement("thead");
  let headerRow = document.createElement("tr");
  let th = document.createElement("th");
  th.innerHTML = "Bill Type"; //header
  th.classList.add("text-center");
  headerRow.appendChild(th);
  th = document.createElement("th");
  th.innerHTML = "Average"; //header
  th.classList.add("text-center");
  headerRow.appendChild(th);
  outlets.forEach(element => {
    th = document.createElement("th");
    th.innerHTML = element; //this one is populating outlet as header
    th.classList.add("text-center");

    headerRow.appendChild(th);

  });

  thead.appendChild(headerRow);
  table.appendChild(thead);

  let tbody = document.createElement("tbody"); // from here onwards i don't know what to do

  let row = document.createElement("tr");

  let total = 0;
  outlets.forEach(outlet => { //i am trying to loop through outlets but getting somthing else
    let el = 0;
    data.forEach(d => {
      if (d.outlet == outlet) {
        total += parseInt(d.cancelled);
        el = d.cancelled;
      }
    });
    td = document.createElement("td");
    td.innerHTML = el.toLocaleString('en-in');
    td.classList.add("text-right");
    row.appendChild(td);
  });
  /* console.log("row is : " , row.children ) */

  tbody.appendChild(row);


  table.appendChild(tbody);
  tbl.innerHTML = "";
  tbl.appendChild(table);
  table.classList.add("table");
  table.classList.add("table-striped");
  table.classList.add("table-bordered");
  table.classList.add("table-hover");
}
let formatedData = formatData(data);
renderTable(formatedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<div align="center" class="table table-responsive">
  <table id="tblOlSalesSummary"></table>
</div>

我不明白为什么要根据销售点循环计算已取消账单和重复账单,然后求平均值。

你的表格布局只有这个还是可以动态改变的?因为如果你想要重复使用它,那么最好使用外部库或格式化你的JSON响应以更适合表格格式。 - j4rey
3个回答

1

我已经在JSFiddle上编写了代码,请看一下。它使用了JQuery。

HTML:

<table id="dataTable">

</table>

JavaScript:

var data = [{
    "outlet": "JAYANAGAR",
    "cancelled": 126544,
    "duplicate": 1
  },
  {
    "outlet": "MALLESHWARAM",
    "cancelled": 31826,
    "duplicate": 31
  },
  {
    "outlet": "KOLAR",
    "cancelled": 10374,
    "duplicate": 10
  }
];


function draw() {
    var avgCancelled = 0;
    var avgDuplicate = 0;
    var totalCancelled = 0;
    var totalDuplicate = 0;
    for (var i = 0; i < data.length; i++) {
        totalCancelled += data[i].cancelled;
        totalDuplicate += data[i].duplicate;
    }
    avgCancelled = totalCancelled / data.length;
    avgDuplicate = totalDuplicate / data.length;
    drawTableHead()
    drawTableRows(avgCancelled, avgDuplicate)
}

function drawTableHead() {
    var row = $("<tr />");
    $("#dataTable").append(row);
    row.append("<th>" + "BILLTYPE"  + "</th>")
    row.append("<th>" + "AVERAGE"  + "</th>")
    for (var i = 0; i < data.length; i++) {
        row.append("<th>" + data[i].outlet  + "</th>")
    }
}

function drawTableRows(avgCancelled, avgDuplicate) {
    var firstRow = $("<tr />");
    $("#dataTable").append(firstRow);
    firstRow.append("<td>" + "CANCELLED BILL"  + "</td>")
    firstRow.append("<td>" + avgCancelled  + "</td>")
    for (var i = 0; i < data.length; i++) {
        firstRow.append("<td>" + data[i].cancelled  + "</td>")
    }
    var secondRow = $("<tr />");
    $("#dataTable").append(secondRow);
    secondRow.append("<td>" + "DUPLICATE BILL"  + "</td>")
    secondRow.append("<td>" + avgDuplicate  + "</td>")
    for (var i = 0; i < data.length; i++) {
        secondRow.append("<td>" + data[i].duplicate  + "</td>")
    }
}


draw();

先生,我也想计算平均值...例如(jayanagar+malleshwaram+kolar)的取消/2=平均值,同样地,对于重复账单,就像我在帖子中提到的那样。 - manish thakur
你的问题中展示的列是否需要动态生成?例如JAYANAGAR、MALLESHWARAM、KOLAR等等。 - Thanthu
是的,它们是动态的...这就是为什么在我的代码中我要计算插座的长度。 - manish thakur
嘿,使用这个JSON [ { "outlet": "JAYANAGAR", "cancelled": 38993, "duplicate": 0 }, { "outlet": "MALLESHWARAM", "cancelled": 10057, "duplicate": 9 }, { "outlet": "KOLAR", "cancelled": 3309, "duplicate": 2 } ] 计算平均值时为什么会出错? - manish thakur
我得到了正确的结果,请替换JSFiddle中的数据并运行以查看结果。 - Thanthu

1

在您的表格billtypeaverage中有两个静态字段列,需要在循环json数据之前添加。

 var outletCount = 0; //global variable to get the no of outlets
var data = [{
    "outlet": "JAYANAGAR",
    "cancelled": 126544,
    "duplicate": 1
  },
  {
    "outlet": "MALLESHWARAM",
    "cancelled": 31826,
    "duplicate": 31
  },
  {
    "outlet": "KOLAR",
    "cancelled": 10374,
    "duplicate": 10
  },
  {
    "outlet": "New Test",
    "cancelled": 154,
    "duplicate": 20
  }
];

let formatData = function(data) { //outlets is unique thats why formating it to loop forward in my code
  let outlets = [];
  data.forEach(element => {
    if (outlets.indexOf(element.outlet) == -1) {
      outlets.push(element.outlet);
    }
  });
  outletCount = outlets.length //calculating outlet count

  return {
    data: data,
    outlets: outlets,

  };
};

let renderTable = function(data) {
  outlets = data.outlets;
  data = data.data;
  let tbl = document.getElementById("tblOlSalesSummary");
  let table = document.createElement("table");
  let thead = document.createElement("thead");
  let headerRow = document.createElement("tr");
  let th = document.createElement("th");
  th.innerHTML = "Bill Type"; //header
  th.classList.add("text-center");
  headerRow.appendChild(th);
  th = document.createElement("th");
  th.innerHTML = "Average"; //header
  th.classList.add("text-center");
  headerRow.appendChild(th);
  outlets.forEach(element => {
    th = document.createElement("th");
    th.innerHTML = element; //this one is populating outlet as header
    th.classList.add("text-center");

    headerRow.appendChild(th);

  });

  thead.appendChild(headerRow);
  table.appendChild(thead);

  let tbody = document.createElement("tbody"); // from here onwards i don't know what to do

  let row = document.createElement("tr");

  let total = 0;

  // static field insertion for Cancelled bill
  let el = 'Cancelled bill';
  td = document.createElement("td");
  td.innerHTML = el.toLocaleString('en-in');
  td.classList.add("text-right");
  row.appendChild(td);
  // Logic start to find the average cancelled amount 
  var total_cancel =0;
  total_can_count = 0;
  outlets.forEach(outlet => { 
    data.forEach(d => {
      if (d.outlet == outlet) {
        total_cancel += parseInt(d.cancelled);
        total_can_count++;

      }
    });
  });

  let el_avg = ( total_cancel / (total_can_count) );
  td = document.createElement("td");
  td.innerHTML = el_avg.toLocaleString('en-in');
  td.classList.add("text-right");
  row.appendChild(td);
  // Logic End to find the average cancelled amount 

  outlets.forEach(outlet => { 
    let el = 0;
    data.forEach(d => {
      if (d.outlet == outlet) {
        total += parseInt(d.cancelled);
        el = d.cancelled;
      }
    });
    td = document.createElement("td");
    td.innerHTML = el.toLocaleString('en-in');
    td.classList.add("text-right");
    row.appendChild(td);
  });

  
  /* console.log("row is : " , row.children ) */

  tbody.appendChild(row);

  let row_duplicate = document.createElement("tr");

  let total_dup = 0;
  // static field insertion for duplicate bill
  let el_2 = 'Duplicate bill';
  td = document.createElement("td");
  td.innerHTML = el_2.toLocaleString('en-in');
  td.classList.add("text-right");
  row_duplicate.appendChild(td);

  // Logic start to find the Duplicate average  
  total_dup_count = 0;
  outlets.forEach(outlet => { 
    data.forEach(d => {
      if (d.outlet == outlet) {
        total_dup += parseInt(d.duplicate);
        total_dup_count++;
      }
    });
  });

  let el_avg_2 = ( total_dup / (total_dup_count) );
  td = document.createElement("td");
  td.innerHTML = el_avg_2.toLocaleString('en-in');
  td.classList.add("text-right");
  row_duplicate.appendChild(td);

  // Logic End to find the Duplicate average  

  outlets.forEach(outlet => { //i am trying to loop through outlets but getting somthing else
    let el = 0;
    data.forEach(d => {
      if (d.outlet == outlet) {
        total += parseInt(d.duplicate);
        el = d.duplicate;
      }
    });
    td = document.createElement("td");
    td.innerHTML = el.toLocaleString('en-in');
    td.classList.add("text-right");
    row_duplicate.appendChild(td);
  });


  /* console.log("row is : " , row.children ) */

  tbody.appendChild(row);
  tbody.appendChild(row_duplicate);

  table.appendChild(tbody);
  tbl.innerHTML = "";
  tbl.appendChild(table);
  table.classList.add("table");
  table.classList.add("table-striped");
  table.classList.add("table-bordered");
  table.classList.add("table-hover");
}
let formatedData = formatData(data);
renderTable(formatedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<div align="center" class="table table-responsive">
  <table id="tblOlSalesSummary"></table>
</div>


嘿,如果你有时间的话,能否检查一下这篇帖子:https://stackoverflow.com/questions/56521258/how-to-display-image-dynamically-on-ui。我在这里卡了很长时间。 - manish thakur

0

使用一个可以从你的 JSON 创建表格的库。

示例:

https://json2html.com/

<script>
    var t = {'<>':'div','html':'${title} ${year}'};

    var d = [
        {"title":"Heat","year":"1995"},
        {"title":"Snatch","year":"2000"},
        {"title":"Up","year":"2009"},
        {"title":"Unforgiven","year":"1992"},
        {"title":"Amadeus","year":"1984"}
    ];

    document.write( json2html.transform(d,t) );
</script>

先生,我不被允许使用外部库,因此我正在使用JavaScript编写自己的代码,请帮助我如果您能的话。 - manish thakur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接