在php中使用rowspan和数组输出到表

时间:2013-05-25 15:12:46

标签: php arrays html-table

我正在修改页面上的表以包含合并的行。

这是处理mysql db输出的php代码:

######## PRINT OUT TABLE WITH YEARS AND OFFICES PLUS NAMES IN CELLS ########    
for ($y = $year_max; $y >=$year_min; $y--){
    echo '<tr><th>'.$y.'</th>';

    for ($i = 0; $i<count($offices_used); $i++){

        if (isset($data[$y][$offices_used[$i]])){
            echo '<td>'.$data[$y][$offices_used[$i]].'</td>';
        } // END IF

        else {
            echo '<td></td>';
        } // END ELSE

        }   echo '</tr>';
    } // END FOR 

下面的表格是从多维数组生成的,例如紧接在下面;

array (  

[2013] => Array
    (
        [President] => John Mills
        [Internal VP] => Virgil Bagdonas
        [External VP] => Reid Gilmore
        [Treasurer] => Todd Heino
        [Secretary] => Eric Holmquist
        [Newsletter] => Art Bodwell
        [Webmaster] => Dave Eaton
        [Photographer] => Rick Angus
        [Video Librarian] => Mike Peters
        [Store Manager] => Kevin Nee
    )

[2012] => Array
    (
        [President] => Dave Eaton
        [Internal VP] => Jim Metcalf
        [External VP] => Reid Gilmore
        [Treasurer] => Mike Peters
        [Secretary] => Eric Holmquist
        [Newsletter] => Art Bodwell
        [Webmaster] => Dave Eaton
        [Photographer] => Peter Wilcox
        [Video Librarian] => Ray Asselin
        [Store Manager] => Joe Giroux
    )

[2011] => Array
    (
        [President] => Charlie Croteau
        [Internal VP] => Reid Gilmore
        [External VP] => Rick Angus
        [Treasurer] => Mike Peters
        [Secretary] => Eric Holmquist
        [Newsletter] => Ron Rocheleau
        [Webmaster] => Dave Eaton
        [Photographer] => Peter Wilcox
        [Video Librarian] => Ray Asselin
        [Book Librarian] => Roger Boisvert
        [Store Manager] => Mike Smith
    )

...等

我的PHP代码NOW从mysql db生成此表:

<tr>
    <th>Year</th>
    <th>President</th>
    <th>Internal VP</th>
    <th>External VP</th>
    <th>Treasurer</th>
    <th>Secretary</th>
    <th>Webmaster</th>
    <th>Newsletter</th>
    <th>Photographer</th>
    <th>Video Librarian</th>
    <th>Book Librarian</th>
    <th>Store Manager</th>
</tr>

<tr>
    <th>2013</th>
    <td>John Mills</td>
    <td>Virgil Bagdonas</td>
    <td>Reid Gilmore</td>
    <td>Todd Heino</td>
    <td>Eric Holmquist</td>
    <td>Dave Eaton</td>
    <td>Art Bodwell</td>
    <td>Rick Angus</td>
    <td>Mike Peters</td>
    <td></td>
    <td>Kevin Nee</td>
</tr>
<tr>
    <th>2012</th>
    <td>Dave Eaton</td>
    <td>Jim Metcalf</td>
    <td>Reid Gilmore</td>
    <td>Mike Peters</td>
    <td>Eric Holmquist</td>
    <td>Dave Eaton</td>
    <td>Art Bodwell</td>
    <td>Peter Wilcox</td>
    <td>Ray Asselin</td>
    <td></td>
    <td>Joe Giroux</td>
</tr>
<tr>
    <th>2011</th>
    <td>Charlie Croteau</td>
    <td>Reid Gilmore</td>
    <td>Rick Angus</td>
    <td>Mike Peters</td>
    <td>Eric Holmquist</td>
    <td>Dave Eaton</td>
    <td>Ron Rocheleau</td>
    <td>Peter Wilcox</td>
    <td>Ray Asselin</td>
    <td>Roger Boisvert</td>
    <td>Mike Smith</td>
</tr>

但是我想要修改数组处理输出以获得以下内容:

<tr>
    <th>Year</th>
    <th>President</th>
    <th>Internal VP</th>
    <th>External VP</th>
    <th>Treasurer</th>
    <th>Secretary</th>
    <th>Webmaster</th>
    <th>Newsletter</th>
    <th>Photographer</th>
    <th>Video Librarian</th>
    <th>Book Librarian</th>
    <th>Store Manager</th>
</tr>
<tr>
    <th>2013</th>
    <td>John Mills</td>
    <td>Virgil Bagdonas</td>
    <td rowspan= "3">Reid Gilmore</td>
    <td>Todd Heino</td>
    <td rowspan="3">Eric Holmquist</td>
    <td rowspan="9">Dave Eaton</td>
    <td rowspan="2">Art Bodwell</td>
    <td>Rick Angus</td>
    <td>Mike Peters</td>
    <td></td>
    <td>Kevin Nee</td>
</tr>
<tr>
    <th>2012</th>
    <td>Dave Eaton</td>
    <td>Jim Metcalf</td>
    <td rowspan="2">Mike Peters</td>
    <td>Peter Wilcox</td>
    <td rowspan="3">Ray Asselin</td>
    <td></td>
    <td>Joe Giroux</td>
</tr>
<tr>
    <th>2011</th>
    <td>Charlie Croteau</td>
    <td>Rick Angus</td>
    <td>Ron Rocheleau</td>
    <td>Peter Wilcox</td>
    <td>Roger Boisvert</td>
    <td>Mike Smith</td>
</tr>

有关如何添加标志或计数器以实现此目的的任何线索都是受欢迎的。谢谢!

3 个答案:

答案 0 :(得分:0)

尝试这个希望工作。(因为我没有运行它,但认为应该工作)。

colspan的代码:

for ($y = $year_max; $y >=$year_min; $y--){
    echo '<tr><th>'.$y.'</th>';

    $lastVal='';
    $buf=array();
    for ($i = 0; $i<count($offices_used); $i++){
        (!isset($data[$y][$offices_used[$i]])?($data[$y][$offices_used[$i]]=''):'');// Im not sure that is really needed

        if($lastVal==$data[$y][$offices_used[$i]]){
            $buf[count($buf)-1]['rep']++;
        }else{
            $lastVal=$data[$y][$offices_used[$i]];
            $buf[]=array('data'=>$lastVal,'rep'=>1);
        }

        foreach($buf as $arr){
            echo '<td'.($arr['rep']>1?' colspan="'.$arr['rep'].'"':'') . '>'.$arr['data'].'</td>';
        }


        }   echo '</tr>';
    } // END FOR 

注意代码更正错误


行距的代码:(我认为它可以比这更简单。我试图做得好。)

$buf=array();
for ($i = 0; $i<count($offices_used); $i++){// this loop makes fill $buf
    $lastVal='';
    for ($y = $year_max; $y >=$year_min; $y--){
        (!isset($data[$y][$offices_used[$i]])?($data[$y][$offices_used[$i]]=''):'');// Im not sure that is really needed
        if($lastVal==$data[$y][$offices_used[$i]]){
            $buf[$i][count($buf[$i])-1]['rep']++;
        }else{
            $lastVal=$data[$y][$offices_used[$i]];
            $buf[$i][$year_max-$y]=array('data'=>$lastVal,'rep'=>1);
        }
    }
}
$mtemp=$year_max;
foreach($buf as $row){
    echo '<tr><th>'.$mtemp.'</th>';
    foreach($row as $rec){
        echo '<td'.($rec['rep']>1?' rowspan="'.$rec['rep'].'"':'') . '>'.$rec['data'].'</td>';
    }
    $mtemp--;
    echo '</tr>';
}

真的希望工作。

通知已更正

答案 1 :(得分:0)

使用:

解决
############################################################################
######## PRINT OUT TABLE WITH YEARS AND OFFICES PLUS NAMES IN CELLS ########    
for ($y = $year_max; $y >=$year_min; $y--){ // Loop through years
    echo '<tr><th>'.$y.'</th>';

    for ($i = 0; $i<count($offices_used); $i++){

        if (isset($data[$y][$offices_used[$i]])){

            $rowz =1;


            if(!($data[$y][$offices_used[$i]] == $data[($y+1)][$offices_used[$i]])){

                while ($data[$y][$offices_used[$i]] == $data[($y-$rowz)][$offices_used[$i]]) $rowz ++; 
                echo '<td rowspan = "'.$rowz.'">'.$data[$y][$offices_used[$i]].'</td>';
            }

        } // END IF

        else {
            echo '<td align = "center"> - </td>';
        } // END ELSE

        }   echo '</tr>';  // End row of current year

} // END FOR Loop through years 
echo '</table>';

有关结果输出页面,请参阅http://jsfiddle.net/eaton9999/8gMVK/

再次感谢imsiso和其他帮助过的人!

答案 2 :(得分:0)

我几天前写了一个可以处理这些东西的图书馆。
看看https://github.com/donquixote/cellbrush

该库的好处是您不需要考虑html中单元格的顺序,以及由于rowspan或colspan需要跳过哪些单元格。相反,您可以在网格中的任何位置“绘制”一个单元格,无论您想要哪个行距或者是colspan。而不是为rowspan或colspan指定一个数字,只需指定rospan / colspan区域的第一个和最后一个行名和列名。

E.g。

$table->td(['2011', '2013'], 'Secretary', 'Eric Holmquist');

以下是一些代码,可以在此库的帮助下创建您要求的表。你仍然需要一些逻辑来计算间隔,但至少你不需要担心表格html的完整性。

(这个问题相当陈旧,但可能仍会有人从Google收听。所以我希望它可能会有用。)

<?php

require_once __DIR__ . '/vendor/autoload.php';

$data = array(
  '2013' => array(
    'President' => 'John Mills',
    'Internal VP' => 'Virgil Bagdonas',
    'External VP' => 'Reid Gilmore',
    'Treasurer' => 'Todd Heino',
    'Secretary' => 'Eric Holmquist',
    'Newsletter' => 'Art Bodwell',
    'Webmaster' => 'Dave Eaton',
    'Photographer' => 'Rick Angus',
    'Video Librarian' => 'Mike Peters',
    'Store Manager' => 'Kevin Nee',
  ),
  '2012' => array(
    'President' => 'Dave Eaton',
    'Internal VP' => 'Jim Metcalf',
    'External VP' => 'Reid Gilmore',
    'Treasurer' => 'Mike Peters',
    'Secretary' => 'Eric Holmquist',
    'Newsletter' => 'Art Bodwell',
    'Webmaster' => 'Dave Eaton',
    'Photographer' => 'Peter Wilcox',
    'Video Librarian' => 'Ray Asselin',
    'Store Manager' => 'Joe Giroux',
  ),
  '2011' => array(
    'President' => 'Charlie Croteau',
    'Internal VP' => 'Reid Gilmore',
    'External VP' => 'Rick Angus',
    'Treasurer' => 'Mike Peters',
    'Secretary' => 'Eric Holmquist',
    'Newsletter' => 'Ron Rocheleau',
    'Webmaster' => 'Dave Eaton',
    'Photographer' => 'Peter Wilcox',
    'Video Librarian' => 'Ray Asselin',
    'Book Librarian' => 'Roger Boisvert',
    'Store Manager' => 'Mike Smith',
  ),
);

// Collect positions to build table columns.
$positions = [];
foreach ($data as $year => $yearData) {
  foreach ($yearData as $position => $person) {
    $positions[$position] = TRUE;
  }
}
$positions = array_keys($positions);

// Define table columns.
$table = (new \Donquixote\Cellbrush\Table())
  ->addColName('year')
  ->addColNames($positions)
;

// Create thead section.
$headRow = $table->thead()->addRow('head');
$headRow->th('year', 'Year');
foreach ($positions as $position) {
  $headRow->th($position, $position);
}

// Create table rows with labels based on year.
$years = array_keys($data);
$table->addRowNames($years);
foreach ($years as $year) {
  $table->th($year, 'year', $year);
}

// Fill table cells in each column.
foreach ($positions as $position) {
  $periodPerson = NULL;
  $periodFirstYear = NULL;
  $periodLastYear = NULL;
  $column = $table->colHandle($position);
  foreach ($years as $year) {
    $person = isset($data[$year][$position])
      ? $data[$year][$position]
      : '-';
    if (!isset($periodFirstYear)) {
      // First year.
      $periodFirstYear = $year;
    }
    elseif ($person !== $periodPerson) {
      // Add a table cell with rowspan.
      $column->td([$periodFirstYear, $periodLastYear], $periodPerson);
      $periodFirstYear = $year;
    }
    $periodPerson = $person;
    $periodLastYear = $year;
  }
  if (isset($periodFirstYear)) {
    // Add a table cell with rowspan.
    $column->td([$periodFirstYear, $periodLastYear], $periodPerson);
  }
}

print $table->render();