Skip to content

Solution to add rowspan to addHTML() (PhpWord/Shared/Html.php) #2787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
majeeed87 opened this issue Jun 5, 2025 · 0 comments
Open

Solution to add rowspan to addHTML() (PhpWord/Shared/Html.php) #2787

majeeed87 opened this issue Jun 5, 2025 · 0 comments

Comments

@majeeed87
Copy link

majeeed87 commented Jun 5, 2025

update the code: phpoffice/phpword/src/PhpWord/Shared/Html.php

add this variable at the beginning of Html class:

protected static $rowIndex = 0;

protected static $columnIndex = 0;

protected static $rowSpanArray = [];

update parseTable method:

protected static function parseTable($node, $element, &$styles)
{
    $elementStyles = self::parseInlineStyle($node, $styles['table']);

    $newElement = $element->addTable($elementStyles);

    // Add style name from CSS Class
    if (isset($elementStyles['className'])) {
        $newElement->getStyle()->setStyleName($elementStyles['className']);
    }
	
	self::$rowIndex = 0;

    $attributes = $node->attributes;
    if ($attributes->getNamedItem('border')) {
        $border = (int) $attributes->getNamedItem('border')->nodeValue;
        $newElement->getStyle()->setBorderSize(Converter::pixelToTwip($border));
    }

    return $newElement;
}

update parseRow method:

protected static function parseRow($node, $element, &$styles)
{
    $rowStyles = self::parseInlineStyle($node, $styles['row']);
    if ($node->parentNode->nodeName == 'thead') {
        $rowStyles['tblHeader'] = true;
    }

    // set cell height to control row heights
    $height = $rowStyles['height'] ?? null;
    unset($rowStyles['height']); // would not apply
	
	self::$columnIndex = 0;
	self::$rowIndex = self::$rowIndex + 1;

    return $element->addRow($height, $rowStyles);
}

update parseCell method:

protected static function parseCell($node, $element, &$styles)
{
	$cellStyles = self::recursiveParseStylesInHierarchy($node, $styles['cell']);
	$vMergeStyle = self::recursiveParseStylesInHierarchy($node, $styles['cell']);
	self::$columnIndex = self::$columnIndex + 1;
	$search_items = ["rowIndex" => self::$rowIndex];
	$rowSpanCell = self::arraySearch(self::$rowSpanArray, $search_items);
	
	
	
	$colspan = $node->getAttribute('colspan');
	if (!empty($colspan)) {
		$cellStyles['gridSpan'] = $colspan - 0;
		self::$columnIndex = self::$columnIndex + $colspan - 1;
	}
	
	$rowspan = $node->getAttribute('rowspan');
	if (!empty($rowspan)) {
		$cellStyles['vMerge'] = 'restart';
		$gridSpan = 0;
		$colIndex = self::$columnIndex;
		if (!empty($colspan)){
			$gridSpan = $colspan;
			$colIndex = self::$columnIndex - $colspan + 1;
		}
		for ($x = 1; $x < $rowspan; $x++) {
		  array_push(self::$rowSpanArray, ['columnIndex'=>$colIndex, 'rowIndex'=>self::$rowIndex + $x, 'colspan'=>$gridSpan]);
		}
	}
	
	$currentColumnRowSpan = self::arraySearch($rowSpanCell, ["columnIndex" => self::$columnIndex]);

	// set cell width to control column widths
	$width = $cellStyles['width'] ?? null;
	unset($cellStyles['width']); // would not apply
	if (count($currentColumnRowSpan) > 0){
		$loop_check = self::$columnIndex;
	} else {
		$cell = $element->addCell($width, $cellStyles);
		$loop_check = self::$columnIndex + 1;
	}
	
	if (count($rowSpanCell) > 0) {
		unset($vMergeStyle['width']);
		foreach($rowSpanCell as $row) {
			if($row['columnIndex'] == $loop_check){
				$loop_check = $row['columnIndex'] + 1;
				
				if ($row['colspan'] > 0) {
					$vMergeStyle['gridSpan'] = $row['colspan'];
					self::$columnIndex = self::$columnIndex + $row['colspan'] + 1;
				} else {
					unset($vMergeStyle['gridSpan']);
					self::$columnIndex = self::$columnIndex + 1;
				}
				$vMergeStyle['vMerge'] = 'continue';
				$element->addCell(null, $vMergeStyle);
			}
		}
	}
	
	if (count($currentColumnRowSpan) > 0){
		$cell = $element->addCell($width, $cellStyles);
	}
	
	if (self::shouldAddTextRun($node)) {
		return $cell->addTextRun(self::filterOutNonInheritedStyles(self::parseInlineStyle($node, $styles['paragraph'])));
	}

	return $cell;
}

add arraySearch method:

// PHP program to search for multiple
// key=>value pairs in array

protected static function arraySearch($array, $search_list)
{
	// Create the result array
	$result = [];

	// Iterate over each array element
	foreach ($array as $key => $value) {
		// Iterate over each search condition
		foreach ($search_list as $k => $v) {
			// If the array element does not meet
			// the search condition then continue
			// to the next element
			if (!isset($value[$k]) || $value[$k] != $v) {
				// Skip two loops
				continue 2;
			}
		}

		// Append array element's key to the
		//result array
		$result[] = $value;
	}

	// Return result
	return $result;
}

Originally posted by @majeeed87 in #2643 (comment)

@majeeed87 majeeed87 changed the title add rowspan to addHTML() (PhpWord/Shared/Html.php) Solution to add rowspan to addHTML() (PhpWord/Shared/Html.php) Jun 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant