Skip to content

Commit 557af99

Browse files
committed
Fix colspan and rowspan for tables in HTML Writer
1 parent 59de019 commit 557af99

File tree

1 file changed

+49
-8
lines changed

1 file changed

+49
-8
lines changed

src/PhpWord/Writer/HTML/Element/Table.php

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,59 @@ public function write()
4040
$rowCount = count($rows);
4141
if ($rowCount > 0) {
4242
$content .= '<table>' . PHP_EOL;
43-
foreach ($rows as $row) {
43+
for ($i = 0; $i < count($rows); $i++) {
4444
/** @var $row \PhpOffice\PhpWord\Element\Row Type hint */
45-
$rowStyle = $row->getStyle();
45+
$rowStyle = $rows[$i]->getStyle();
4646
// $height = $row->getHeight();
4747
$tblHeader = $rowStyle->isTblHeader();
4848
$content .= '<tr>' . PHP_EOL;
49-
foreach ($row->getCells() as $cell) {
50-
$writer = new Container($this->parentWriter, $cell);
51-
$cellTag = $tblHeader ? 'th' : 'td';
52-
$content .= "<{$cellTag}>" . PHP_EOL;
53-
$content .= $writer->write();
54-
$content .= "</{$cellTag}>" . PHP_EOL;
49+
$rowCells = $rows[$i]->getCells();
50+
for ($j = 0; $j < count($rowCells); $j++) {
51+
$cellStyle = $rowCells[$j]->getStyle();
52+
$cellColSpan = $cellStyle->getGridSpan();
53+
$cellRowSpan = 1;
54+
$cellVMerge = $cellStyle->getVMerge();
55+
// If this is the first cell of the vertical merge, find out how man rows it spans
56+
if ($cellVMerge === 'restart') {
57+
for ($k = $i + 1; $k < count($rows); $k++) {
58+
$kRowCells = $rows[$k]->getCells();
59+
if (isset($kRowCells[$j])) {
60+
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
61+
$cellRowSpan++;
62+
} else {
63+
break;
64+
}
65+
} else {
66+
break;
67+
}
68+
}
69+
}
70+
// Ignore cells that are merged vertically with previous rows
71+
if ($cellVMerge !== 'continue') {
72+
$cellTag = $tblHeader ? 'th' : 'td';
73+
$cellColSpanAttr = (is_numeric($cellColSpan) && ($cellColSpan > 1) ? " colspan=\"{$cellColSpan}\"" : "");
74+
$cellRowSpanAttr = ($cellRowSpan > 1 ? " rowspan=\"{$cellRowSpan}\"" : "");
75+
$content .= "<{$cellTag}{$cellColSpanAttr}{$cellRowSpanAttr}>" . PHP_EOL;
76+
$writer = new Container($this->parentWriter, $rowCells[$j]);
77+
$content .= $writer->write();
78+
if ($cellRowSpan > 1) {
79+
// There shouldn't be any content in the subsequent merged cells, but lets check anyway
80+
for ($k = $i + 1; $k < count($rows); $k++) {
81+
$kRowCells = $rows[$k]->getCells();
82+
if (isset($kRowCells[$j])) {
83+
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
84+
$writer = new Container($this->parentWriter, $kRowCells[$j]);
85+
$content .= $writer->write();
86+
} else {
87+
break;
88+
}
89+
} else {
90+
break;
91+
}
92+
}
93+
}
94+
$content .= "</{$cellTag}>" . PHP_EOL;
95+
}
5596
}
5697
$content .= '</tr>' . PHP_EOL;
5798
}

0 commit comments

Comments
 (0)