使用JSON数据创建HTML表格时遇到问题

5

在使用JSON数据创建HTML表格时,我遇到了问题,由于我对此不熟悉,因此无法正确编写逻辑。

我有一个JSON数据,需要创建动态HTML表格。由于表格的设计比较复杂,因此我无法正确地填充HTML表格与正确的数据。

我正在尝试从我的JSON创建以下内容:

table like this

但无法做到。

我已经做了类似这样的事情

var data = [{
    "billdate": "2018-08-01",
    "outlet": "S0001",
    "amount": 291589,
    "cash": 288276,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 3313,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-01",
    "outlet": "S0002",
    "amount": 58337,
    "cash": 56727,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 1610,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-01",
    "outlet": "S0009",
    "amount": 65970,
    "cash": 65970,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 0,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0001",
    "amount": 296125,
    "cash": 290480,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 5645,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0002",
    "amount": 56545,
    "cash": 55034,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 1511,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0009",
    "amount": 72213,
    "cash": 72213,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 0,
    "kb": 0,
    "bigbasket": 0
  }
]


let formatData = function(data) {
  let billdates = [];
  let outlets = [];
  data.forEach(element => {
    if (billdates.indexOf(element.billdate) == -1) {
      billdates.push(element.billdate);
    }
    if (outlets.indexOf(element.outlet) == -1) {
      outlets.push(element.outlet);
    }
  });
  return {
    data: data,
    billdates: billdates,
    outlets: outlets,

  };
};

let renderTable = function(data) {
  billdates = data.billdates;
  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 = "BillDate";
  th.classList.add("text-center");
  headerRow.appendChild(th);
  let grandTotal = 0;
  let outletWiseTotal = {};
  th = document.createElement("th");
  th.innerHTML = "Sales Type";
  th.classList.add("text-center");
  headerRow.appendChild(th);
  outlets.forEach(element => {
    th = document.createElement("th");
    th.innerHTML = element;
    th.classList.add("text-center");

    headerRow.appendChild(th);
    outletWiseTotal[element] = 0;
    data.forEach(el => {
      if (el.outlet == element) {
        outletWiseTotal[element] += parseInt(el.amount);
      }
    });
    grandTotal += outletWiseTotal[element];
  });

  thead.appendChild(headerRow);
  headerRow = document.createElement("tr");
  th = document.createElement("th");
  th.innerHTML = "Total";
  th.classList.add("text-center");
  headerRow.appendChild(th);

  outlets.forEach(element => {
    th = document.createElement("th");
    th.innerHTML = outletWiseTotal[element].toLocaleString('en-in');
    th.classList.add("text-right");

    headerRow.appendChild(th);
  });
  th = document.createElement("th");
  th.innerHTML = grandTotal.toLocaleString('en-in');
  th.classList.add("text-right");

  /* console.log(grandTotal); */
  // headerRow.appendChild(th);
  headerRow.insertBefore(th, headerRow.children[1]);
  thead.appendChild(headerRow);
  table.appendChild(thead);

  let tbody = document.createElement("tbody");
  billdates.forEach(element => {
    let row = document.createElement("tr");
    td = document.createElement("td");
    td.innerHTML = element;
    row.appendChild(td);
    let total = 0;
    outlets.forEach(outlet => {
      let el = 0;
      data.forEach(d => {
        if (d.billdate == element && d.outlet == outlet) {
          total += parseInt(d.cash);
          el = d.cash;
        }
      });
      td = document.createElement("td");
      td.innerHTML = el.toLocaleString('en-in');
      td.classList.add("text-right");
      row.appendChild(td);
    });
    /* console.log("row is : " , row.children ) */
    td = document.createElement("td");
    td.innerHTML = total.toLocaleString('en-in');
    td.classList.add("text-right");
    // row.appendChild(td);
    row.insertBefore(td, row.children[1]);
    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">
  <table id="tblOlSalesSummary">
  </table>
</div>

根据我的图片,我需要按账单日期循环数据,这就是我卡住的地方。我上传的图片仅供参考,请不要匹配那里的值,图片和我的JSON的所有值都不同,但Full Total Total只能基于此计算。
我知道如何创建动态表格,但在这里,我遇到了一些循环场景。
我的表格完全动态,所有数据都是根据用户选择从数据库中获取的。
编辑
我已经在我的JSON数据中添加了金额,这是按账单日期总计的,因此无需通过编码计算。
金额为:每个出口的日期总计

不是直接的解决方案,但是使用HTML模板化,没有人会快速理解你的表格是如何构建的。例如:https://handlebarsjs.com/ - Wimanicesir
2个回答

1

我已经得到了与您发布的图片类似的输出。我代码唯一可能的缺点是需要一个硬编码的“销售类型”数组,因此如果JSON数据是一致的且不会更改,则可以使用此代码,否则很容易解析对象并每次创建一个全新的“销售类型”数组。

基本思路是我解析了主对象并将其转换为这个对象

Object{
  date1:{
    outlet1: {
            service1: value,
            service2: value

            },
     outlet2: {
            service1: value,
            service2: value

             }
           }
 date2:{
    outlet1: {
            service1: value,
            service2: value

  }
    ...and so on
}

然后,循环遍历该对象以在DOM上呈现表格。

var data = [{
    "billdate": "2018-08-01",
    "outlet": "S0001",
    "amount": 291589,
    "cash": 288276,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 3313,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-01",
    "outlet": "S0002",
    "amount": 58337,
    "cash": 56727,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 1610,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-01",
    "outlet": "S0009",
    "amount": 65970,
    "cash": 65970,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 0,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0001",
    "amount": 296125,
    "cash": 290480,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 5645,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0002",
    "amount": 56545,
    "cash": 55034,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 1511,
    "kb": 0,
    "bigbasket": 0
  },
  {
    "billdate": "2018-08-02",
    "outlet": "S0009",
    "amount": 72213,
    "cash": 72213,
    "creditcard": 0,
    "coupon": 0,
    "paytm": 0,
    "credit": 0,
    "swiggy": 0,
    "kb": 0,
    "bigbasket": 0
  }
]


let formatData = function(data) {
  let formattedData = {};
  data.forEach(element => {
    if (!formattedData.hasOwnProperty(element.billdate)){
      formattedData[element.billdate] = {};
    }
  });
  
Object.keys(formattedData).forEach(function(key) {
   //console.log(key, formattedData[key]);
  data.forEach(element => {
    if(key == element.billdate){
      formattedData[key][element.outlet] = {'amount': element.amount,
                                           'cash': element.cash,
                                           'creditcard': element.creditcard,
                                            'coupon': element.coupon,
                                            'paytm': element.paytm,
                                            'credit': element.credit,
                                            'swiggy': element.swiggy,
                                            'kb': element.kb,
                                            'bigbasket': element.bigbasket
                                           };
    }
  });
  
});
  
  //console.log(formattedData);
  return formattedData;
}





let renderTable = function(data) {
  //console.log(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 = "BillDate";
  th.classList.add("text-center");
  headerRow.appendChild(th);
  
  th = document.createElement("th");
  th.innerHTML = "Sales Type";
  th.classList.add("text-center");
  headerRow.appendChild(th);
  
  let outletArray = [];
  Object.keys(data).forEach(element => {
    let obj = data[element];
    //console.log(obj);
    Object.keys(obj).forEach(elem => {
      if(outletArray.indexOf(elem) == -1){
        outletArray.push(elem);
      }
    });
  });
  //console.log(outletArray);
  
 
  
  outletArray.forEach(element => {
    th = document.createElement("th");
    th.innerHTML = element;
    th.classList.add("text-center");
    headerRow.appendChild(th);
  });

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

   let tbody = document.createElement("tbody");
  
   
  //full total
  let fullTotal = {};
  outletArray.forEach(elem => {
    fullTotal[elem] = 0;
    Object.keys(data).forEach(element => {

         fullTotal[elem] += data[element][elem]["amount"];
    
    })
  })
  //console.log(fullTotal);
  
  let row = document.createElement("tr");
  td = document.createElement("td");
   td.innerHTML = "";
  row.appendChild(td);
  td = document.createElement("td");
   td.innerHTML = "Full Total";
  row.appendChild(td);
  Object.keys(fullTotal).forEach(elem =>{
    td = document.createElement("td");
   td.innerHTML = fullTotal[elem];
     row.appendChild(td);
  })
 
  tbody.appendChild(row);

  
  
  
  
  
  let salesTypes = ["amount","cash","creditcard","coupon","paytm","credit","swiggy","kb","bigbasket"];
  
  Object.keys(data).forEach(element => {
    
    
    let salesTypesIndex = 0;
   salesTypes.forEach(elem => {
     let row = document.createElement("tr");
     td = document.createElement("td");
     if(salesTypesIndex == 0){
    td.innerHTML = element;
     }else{
    td.innerHTML = "";
     }
    
    row.appendChild(td);
    td = document.createElement("td");
     if(elem == "amount"){
       td.innerHTML = "Totals";
     }else{
        td.innerHTML = elem;
     }
   
    row.appendChild(td);
     
     outletArray.forEach(elem2 => {
       let value = data[element][elem2][elem];
       //console.log("value:",value);
        td = document.createElement("td");
       td.innerHTML = value;
       row.appendChild(td);
     })

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

    tbody.appendChild(row);
     
     salesTypesIndex++;
   })
   
  });

  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 formattedData = formatData(data);
renderTable(formattedData);
<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">
  <table id="tblOlSalesSummary">
  </table>
</div>


销售类型并非硬编码,但我已经找到了解决方案。 - user10705797
@viveksingh 当然,我只是为了简单起见硬编码了,但它可以很容易地从JSON响应中构建。 - vikrant

0
也许可以帮到你。你应该组织好你的数据,然后按逻辑建立表格。
建立一个包含所有Sx和总值的数组, 建立一个包含所有日期和总值的数组, 建立一个包含总计的数组, 等等。
table:
  head and row
  - date cell
  - sales cell
  - foreach Sx a cell

  another row
  - empty cell
  - fulltotal cell
  - foreach Sx totalvalues cells

  body
    foreach date a row with
    - date cell
    - total cell
    - totalvalues cells on each Sx

    forech field in date a row with
      - empty cell
      - name cell
      - foreach sX a cell with value

但是我无法进行计算... 我对逻辑和基础知识不是很熟悉,这就是为什么我提出这个问题... 如果您能编写一些有用的代码,那将非常有帮助。 - user10705797
你需要将总构建与HTML构建分开,这样当你将所有想要的数据放进数组后,就可以构建表格并从这里获取总数,例如outletWiseTotal。使用你的formatData函数保存键和总数,然后构建。 - grupowebex
你的意思是我应该在JavaScript中计算后端传来的amount吗? - user10705797
outletWiseTotal,grandTotal,total += parseInt(d.cash) 这都是在JavaScript上吗? - grupowebex
在我的JSON中,outletWiseTotal是我用作“amount”的总计,而“full total”应该在JavaScript中计算。 - user10705797
请帮忙,如果您能的话。 - user10705797

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