Skip to content

Commit 2896edf

Browse files
authored
Add rowspan for the table
1 parent 0ab0b49 commit 2896edf

File tree

1 file changed

+99
-10
lines changed

1 file changed

+99
-10
lines changed

src/PhpWord/Shared/Html.php

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ class Html
4747

4848
protected static $options;
4949

50+
protected static $rowIndex = 0;
51+
52+
protected static $columnIndex = 0;
53+
54+
protected static $rowSpanArray = [];
55+
5056
/**
5157
* @var Css
5258
*/
@@ -424,6 +430,9 @@ protected static function parseTable($node, $element, &$styles)
424430
$newElement->getStyle()->setStyleName($elementStyles['className']);
425431
}
426432

433+
self::$rowIndex = 0;
434+
self::$rowSpanArray = [];
435+
427436
$attributes = $node->attributes;
428437
if ($attributes->getNamedItem('border')) {
429438
$border = (int) $attributes->getNamedItem('border')->nodeValue;
@@ -453,6 +462,9 @@ protected static function parseRow($node, $element, &$styles)
453462
$height = $rowStyles['height'] ?? null;
454463
unset($rowStyles['height']); // would not apply
455464

465+
self::$columnIndex = 0;
466+
self::$rowIndex = self::$rowIndex + 1;
467+
456468
return $element->addRow($height, $rowStyles);
457469
}
458470

@@ -468,22 +480,99 @@ protected static function parseRow($node, $element, &$styles)
468480
protected static function parseCell($node, $element, &$styles)
469481
{
470482
$cellStyles = self::recursiveParseStylesInHierarchy($node, $styles['cell']);
483+
$vMergeStyle = self::recursiveParseStylesInHierarchy($node, $styles['cell']);
484+
self::$columnIndex = self::$columnIndex + 1;
485+
$search_row_items = ["rowIndex" => self::$rowIndex];
486+
$rowSpanCell = array_filter(self::$rowSpanArray, function ($item) use ($search_row_items) {
487+
return count(array_intersect_assoc($search_row_items, $item)) == count($search_row_items);
488+
});
471489

472490
$colspan = $node->getAttribute('colspan');
473491
if (!empty($colspan)) {
474492
$cellStyles['gridSpan'] = $colspan - 0;
493+
self::$columnIndex = self::$columnIndex + $colspan - 1;
475494
}
476495

477-
// set cell width to control column widths
478-
$width = $cellStyles['width'] ?? null;
479-
unset($cellStyles['width']); // would not apply
480-
$cell = $element->addCell($width, $cellStyles);
481-
482-
if (self::shouldAddTextRun($node)) {
483-
return $cell->addTextRun(self::filterOutNonInheritedStyles(self::parseInlineStyle($node, $styles['paragraph'])));
484-
}
485-
486-
return $cell;
496+
$rowspan = $node->getAttribute('rowspan');
497+
if (!empty($rowspan)) {
498+
$cellStyles['vMerge'] = 'restart';
499+
$gridSpan = 0;
500+
$colIndex = self::$columnIndex;
501+
if (!empty($colspan)){
502+
$gridSpan = $colspan;
503+
$colIndex = self::$columnIndex - $colspan + 1;
504+
}
505+
for ($x = 1; $x < $rowspan; $x++) {
506+
array_push(self::$rowSpanArray, ['columnIndex'=>$colIndex, 'rowIndex'=>self::$rowIndex + $x, 'colspan'=>$gridSpan]);
507+
}
508+
}
509+
510+
$search_column_item = ["columnIndex" => self::$columnIndex];
511+
$currentColumnRowSpan = array_filter($rowSpanCell, function ($item) use ($search_column_item) {
512+
return count(array_intersect_assoc($search_column_item, $item)) == count($search_column_item);
513+
});
514+
515+
// set cell width to control column widths
516+
$width = $cellStyles['width'] ?? null;
517+
unset($cellStyles['width']); // would not apply
518+
$loop_check = self::$columnIndex;
519+
if (count($currentColumnRowSpan) == 0){
520+
$cell = $element->addCell($width, $cellStyles);
521+
$loop_check = self::$columnIndex + 1;
522+
}
523+
524+
if (count($rowSpanCell) > 0) {
525+
unset($vMergeStyle['width']);
526+
foreach($rowSpanCell as $row) {
527+
if($row['columnIndex'] == $loop_check){
528+
$loop_check = $row['columnIndex'] + 1;
529+
530+
if ($row['colspan'] > 0) {
531+
$vMergeStyle['gridSpan'] = $row['colspan'];
532+
self::$columnIndex = self::$columnIndex + $row['colspan'] + 1;
533+
} else {
534+
unset($vMergeStyle['gridSpan']);
535+
self::$columnIndex = self::$columnIndex + 1;
536+
}
537+
$vMergeStyle['vMerge'] = 'continue';
538+
$element->addCell($width, $vMergeStyle);
539+
}
540+
}
541+
}
542+
543+
if (count($currentColumnRowSpan) > 0){
544+
$cell = $element->addCell($width, $cellStyles);
545+
}
546+
547+
$search_item = ["columnIndex" => self::$columnIndex + 1];
548+
$nextColumnRowSpan = array_filter($rowSpanCell, function ($item) use ($search_item) {
549+
return count(array_intersect_assoc($search_item, $item)) == count($search_item);
550+
});
551+
552+
if (count($nextColumnRowSpan) > 0) {
553+
unset($vMergeStyle['width']);
554+
$loop_check = self::$columnIndex + 1;
555+
foreach($rowSpanCell as $row) {
556+
if($row['columnIndex'] == $loop_check){
557+
$loop_check = $row['columnIndex'] + 1;
558+
if ($row['colspan'] > 0) {
559+
$vMergeStyle['gridSpan'] = $row['colspan'];
560+
self::$columnIndex = self::$columnIndex + $row['colspan'] + 1;
561+
} else {
562+
unset($vMergeStyle['gridSpan']);
563+
self::$columnIndex = self::$columnIndex + 1;
564+
}
565+
$vMergeStyle['vMerge'] = 'continue';
566+
$element->addCell($width, $vMergeStyle);
567+
}
568+
}
569+
}
570+
571+
if (self::shouldAddTextRun($node)) {
572+
return $cell->addTextRun(self::filterOutNonInheritedStyles(self::parseInlineStyle($node, $styles['paragraph'])));
573+
}
574+
575+
return $cell;
487576
}
488577

489578
/**

0 commit comments

Comments
 (0)