PHP之根据树形数组生成table表格并且合并单元格
数据格式如下:
0 =>
array (size=12)
'root_id' => string '0' (length=1)
'parent_id' => string '0' (length=1)
'field_id' => string '10' (length=2)
'field_name' => string '测试指标1' (length=13)
'order_num' => string '1' (length=1)
'path' => string '1' (length=1)
1 =>
array (size=12)
'root_id' => string '10' (length=2)
'parent_id' => string '10' (length=2)
'field_id' => string '16' (length=2)
'field_name' => string '指标1-2' (length=9)
'order_num' => string '1' (length=1)
'path' => string '2' (length=1)
2 =>
array (size=12)
'root_id' => string '10' (length=2)
'parent_id' => string '16' (length=2)
'field_id' => string '17' (length=2)
'field_name' => string '指标1-2-1' (length=11)
'order_num' => string '2' (length=1)
'path' => string '3' (length=1)
3 =>
array (size=12)
'root_id' => string '10' (length=2)
'parent_id' => string '16' (length=2)
'field_id' => string '18' (length=2)
'field_name' => string '指标1-2-1-1' (length=13)
'order_num' => string '2' (length=1)
4 =>
array (size=12)
'root_id' => string '10' (length=2)
'parent_id' => string '16' (length=2)
'field_id' => string '21' (length=2)
'field_name' => string '指标1-2-1-1' (length=13)
'order_num' => string '2' (length=1)
'path' => string '3' (length=1)
构思:
1、将数组先组合成
// array(
// [ 'z1'=>'测试指标1',
// 'z2'=>'指标1-2',
// 'z3'=>'指标1-2-1',
// ],
// [
// 'z1'=>'测试指标1',
// 'z2'=>'指标1-1',
// 'z3'=>'指标1-1-1',
// ]
// )
2、然后在合并
代码如下:
/**
* 数据集合循环递归
*
* @return void
*/
public function getTrees($data = [], $pid = 0)
{
static $list = [];
foreach ($data as $key => $vals) {
if ($vals['parent_id'] == $pid) {
$list[] = $vals;
unset($data[$key]);
$this->getTrees($data, $vals['field_id']);
}
}
return $list;
}
$trees = $this->getTrees($fields);
foreach ($trees ?? [] as $key => $vals) {
if ($vals['root_id'] == 0) {
$treedata[$vals['field_id']][$vals['path']] += 1;
$treedata[$vals['field_id']]['counts'] = $i;
} else {
$i++;
$treedata[$vals['root_id']][$vals['path']] += 1;
$treedata[$vals['root_id']]['counts'] = $i;
}
}
$mpath=4; //最大列数
$mergeData = [];
$datas = [];
$data_array = [];
//先根据数值获取最大的行数
$slice_max = 0;
$key = 0;
foreach ($treedata as $keys => $vals) {
if ($key == 0) $slice_max = 0;
$slice_array = array_slice($trees ?? [], $slice_max, $vals['counts']);
$max_array = end($vals);
if ($max_array <= 0) {
continue;
}
//开始数据组合 先组行数
foreach (range(1, $max_array) as $ks => $vs) {
$mergeData = [];
//数据循环来换行
foreach ($slice_array ?? [] as $ks1 => $vs1) {
$mergeData['z' . $vs1['path']] = $vs1['field_name'];
if ($vs1['path'] == $mpath) {
unset($slice_array[$ks1]);
break;
}
}
$data_array[] = $mergeData;
}
$key++;
$slice_max += $vals['counts'];
}
$mreges = $this->mergeTables($data_array);
public function mergeTables($arrays = [], $columns = ['z1', 'z2'])
{
//计算数据合并
foreach ($columns as $key1 => $vals1) {
$mrege = 1;
//数据开始循环
foreach ($arrays as $key => $vals) {
if ($arrays[$key][$vals1] == $arrays[$key - 1][$vals1]) {
//数据合并
$mrege += 1;
$datas[$vals[$vals1]] = $mrege;
} else {
$mrege = 1;
}
}
}
return $datas;
}
$tables = $this->getTableds($data_array, $mreges);
/**
* 组合数据结果
*
* @param [type] $mpath
* @param [type] $fields
* @param [type] $trees
* @return void
*/
public function getTableds($arrays, $mreges)
{
$htmls = '';
$counts = [];
foreach ($arrays as $key => $vals) {
$strs = '<tr>';
//第一个数据进行rowsoan 剩下的不写
$columns = ['z1', 'z2', 'z3'];
foreach ($columns as $k1) {
if (empty($mreges[$vals[$k1]])) {
$strs .= '<td>' . $vals[$k1] . '</td>';
}
//有rowsoan数据
if ($mreges[$vals[$k1]] > 0) {
$counts[$vals[$k1]] += 1;
if ($counts[$vals[$k1]] == 1) {
$rowspan = ' rowspan="' . $mreges[$vals[$k1]] . '"';
$strs .= '<td' . $rowspan . '>' . $vals[$k1] . '</td>';
}
}
}
$strs .= '<td>' . $vals['gcdian'] . '</td>';
$strs .= '<td>' . $vals['flzcyj'] . '</td>';
$strs .= '<td>' . $vals['sbcl'] . '</td>';
$strs .= '<td>' . $vals['ckfz'] . '</td>';
$strs .= '</tr>';
$htmls .= $strs;
}
return $htmls;
}
样子: