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

时间:2019-02-27 10:33:11

标签: javascript jquery json html-table

在创建带有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仅应基于此值进行计算。

我知道如何创建动态表,但是在这里我陷入了一些循环情况。

我的表是完全动态的,所有数据都是根据用户选择来自db的。

编辑

我在JSON数据中添加了金额,这是账单总额,因此无需通过编码进行计算。

金额为:每个网点的total日期明智

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

也许可以帮上忙。您应该整理数据,然后使用逻辑构建表

使用所有Sx和totalvalue建立一个数组 用所有日期和总值构建一个数组 用总计构建一个数组 等

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