根据每行列的内容将一个大表拆分为多个表

Posted

技术标签:

【中文标题】根据每行列的内容将一个大表拆分为多个表【英文标题】:Split one big table into multiple tables based on content of acolumn in each row 【发布时间】:2021-12-17 01:54:42 【问题描述】:

我查看了之前的类似问题,只找到了一个答案,以下代码将数据拆分为 2 个表:

    // ==UserScript==
// @name        TABLE SPLITTER
// @namespace   http://www.w3schools.com/
// @description DESCRIPTION!!!
// @include     http://www.w3schools.com/css/css_table.asp
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require     https://raw.github.com/tomgrohl/jQuery-plugins/master/jcookie/script/jquery.jcookie.min.js
// @version     1
// ==/UserScript==
$(function()
        // YOUR javascript CODE HERE
        // YOU HAVE JQUERY INCLUDED
    setTimeout(function()
        var mainTable = $("table");
        var splitBy = 3;
        var rows = mainTable.find ( "tr" ).slice( splitBy );
        var secondTable = $("<table id='secondTable' style='background:pink;'><tbody></tbody></table>").insertAfter("table");
        secondTable.find("tbody").append(rows);
        console.log(secondTable);
        mainTable.find ( "tr" ).slice( splitBy ).remove();

    , 3000);
);

我正在寻找这样的东西,它会根据我拥有的不同选项的数量将信息拆分到表格中。

最后我想要这样的东西: Goal

或者甚至更好地从输出中删除类型并将其显示在每个新表之前,如下所示:option 2

不确定这是否可能,并希望得到一些帮助。

【问题讨论】:

我会推荐DataTables 【参考方案1】:

这不是最佳解决方案,你可以得到想法并改进它。

读取 JS cmets。

var dynamicData = $('#dynamicData'); // To identify the parent that we will append data to.

$(document).ready(function()

  $('.types').each(function() // loop on each type and check if that type not appended inside '#dynamicData' as 'h5', if no,t append it and append a table related to it
    var name = $.trim($(this).text());
    var check = $('h5#i_' + name , dynamicData).length;
    if (check === 0)
      $(dynamicData).append('<h5 id="i_' + name + '">' + name + '</h5>');      
      $(dynamicData).append('<table id="t_' + name + '" class="table table-hover table-striped table-bordered"></table>');
      $('table#t_' + name).append('<thead>'+
        '<tr>'+
        '<th>Product</th>'+
        '<th>Price</th>'+
        '</tr>'+
        '</thead>'+
        '<tbody>'+
      '</tbody>');
    
  );
  
  $('#allContent > tr').each(function() // loop on each row in '#allContent' and read '.types' class, then clone this row and remove the type then append it inside the target table using id
    var name = $.trim($('.types',this).text());
    $(this).clone().find('.types').remove().end().appendTo('table#t_' + name + ' > tbody');
  );
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">


<h4 class="text-center text-danger">Before:</h4>
<table class="table table-hover table-striped table-bordered">
  <thead>  
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody id="allContent">
    <tr>
      <td>TV</td>
      <td>250$</td>
      <td class="types">Product</td>
    </tr>
    <tr>
      <td>Channel</td>
      <td>1$</td>
      <td class="types">Service</td>
    </tr>
    <tr>
      <td>Channel</td>
      <td>1$</td>
      <td class="types">Service</td>
    </tr>
    <tr>
      <td>DVD</td>
      <td>14$</td>
      <td class="types">Product</td>
    </tr>
    <tr>
      <td>Support</td>
      <td>15$</td>
      <td class="types">Team</td>
    </tr>
  </tbody>
</table>

<h4 class="text-center text-danger">After:</h4>
<div id="dynamicData"></div>

【讨论】:

感谢您的回答,我会尝试调整它以使其正常工作,我的表格和 html 是由自动化系统创建的,因此表格缺少 id 和标签。这就是为什么我使用 var mainTable = $("table"); var splitBy = 3;【参考方案2】:

我的第一个想法是制作一个独特的类型列表。然后遍历该列表,为每个列表克隆原始表。然后遍历克隆的表并删除您不想要的所有内容。绝对不是最有效的,但它很简单而且很有效。

let types = [... new Set($('table.original tr td:last-of-type')
              .get().map(type => type.textContent))];

//create a container for the cloned tables
$('table.original').after(`<h4>After:</h4><div class="cloned-tables"></div>`)

//loop over types, clone tables, modify accordingly
$.each(types, function(index, type) 
  $(`<p class="type">$type</p>$$('table.original')[0].outerHTML`)
    .appendTo('.cloned-tables')
    .find('tr td:last-of-type').each(function() 
      if (this.textContent !== type)  this.parentElement.remove();          
      this.remove();
  );
);

//remove all type header cells
$(`.cloned-tables table th:last-of-type`).remove();
h4color: red;
.typecolor: blue;
<h4>Before:</h4>
<table class="original">
  <thead>  
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>TV</td>
      <td>$250</td>
      <td>Product</td>
    </tr>
    <tr>
      <td>Channel</td>
      <td>$1</td>
      <td>Service</td>
    </tr>
    <tr>
      <td>Channel</td>
      <td>$1</td>
      <td>Service</td>
    </tr>
    <tr>
      <td>DVD</td>
      <td>$14</td>
      <td>Product</td>
    </tr>
    <tr>
      <td>Support</td>
      <td>$15</td>
      <td>Team</td>
    </tr>
  </tbody>
</table>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

关于使用greasemonkey 的另一个想法是,在尝试对其进行任何操作之前,请确保该表存在并且已填充。 Greasemonkey 与原始代码的范围不同,因此document.ready() 不准确。有时事情加载非常异步,这会使有效代码看起来很糟糕。我倾向于做这样的事情:

let loading = setInterval(function() 
  if ($('table.original').length) 
    clearInterval(loading);
    //greasmonkey code here
  
, 1000);

【讨论】:

以上是关于根据每行列的内容将一个大表拆分为多个表的主要内容,如果未能解决你的问题,请参考以下文章

VBA代码根据列的内容将excel文件拆分为多个工作簿?

mysql把一个大表拆分多个表后,如何解决跨表查询效率问题

SQL - 根据访问频率拆分大表?

将大表查询拆分为对表子集的多个查询是不是有意义?

OGG,大表拆分

MySQL:将大表拆分为分区或单独的表?