Html parser (addHtml) - support vertical-align, valign

This commit is contained in:
lubosdz 2020-07-11 22:47:40 +02:00
parent 108c1cdc55
commit 3066d47003
2 changed files with 86 additions and 4 deletions

View File

@ -96,19 +96,19 @@ class Html
$attributes = $node->attributes; // get all the attributes(eg: id, class) $attributes = $node->attributes; // get all the attributes(eg: id, class)
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$val = trim($attribute->value);
switch (strtolower($attribute->name)) { switch (strtolower($attribute->name)) {
case 'style': case 'style':
$styles = self::parseStyle($attribute, $styles); $styles = self::parseStyle($attribute, $styles);
break; break;
case 'align': case 'align':
$styles['alignment'] = self::mapAlign($attribute->value); $styles['alignment'] = self::mapAlign($val);
break; break;
case 'lang': case 'lang':
$styles['lang'] = $attribute->value; $styles['lang'] = $val;
break; break;
case 'width': case 'width':
// tables, cells // tables, cells
$val = trim($attribute->value);
if(false !== strpos($val, '%')){ if(false !== strpos($val, '%')){
// e.g. <table width="100%"> or <td width=50%> // e.g. <table width="100%"> or <td width=50%>
$styles['width'] = intval($val) * 50; $styles['width'] = intval($val) * 50;
@ -126,7 +126,13 @@ class Html
break; break;
case 'bgcolor': case 'bgcolor':
// tables, rows, cells e.g. <tr bgColor="#FF0000"> // tables, rows, cells e.g. <tr bgColor="#FF0000">
$styles['bgColor'] = trim($attribute->value, '# '); $styles['bgColor'] = trim($val, '# ');
break;
case 'valign':
// cells e.g. <td valign="middle">
if (preg_match('#(?:top|bottom|middle|baseline)#i', $val, $matches)) {
$styles['valign'] = self::mapAlignVertical($matches[0]);
}
break; break;
} }
} }
@ -678,6 +684,12 @@ class Html
$styles["border{$which}Style"] = self::mapBorderStyle($matches[3]); $styles["border{$which}Style"] = self::mapBorderStyle($matches[3]);
} }
break; break;
case 'vertical-align':
// https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align
if (preg_match('#(?:top|bottom|middle|sub|baseline)#i', $cValue, $matches)) {
$styles['valign'] = self::mapAlignVertical($matches[0]);
}
break;
} }
} }
@ -842,6 +854,32 @@ class Html
} }
} }
/**
* Transforms a HTML/CSS alignment into a \PhpOffice\PhpWord\SimpleType\Jc
*
* @param string $cssAlignment
* @return string|null
*/
protected static function mapAlignVertical($alignment)
{
$alignment = strtolower($alignment);
switch ($alignment) {
case 'top':
case 'baseline':
case 'bottom':
return $alignment;
case 'middle':
return 'center';
case 'sub':
return 'bottom';
case 'text-top':
case 'baseline':
return 'top';
default:
return '';
}
}
/** /**
* Map list style for ordered list * Map list style for ordered list
* *

View File

@ -844,4 +844,48 @@ HTML;
$this->assertTrue($doc->elementExists($xpath, $xmlFile)); $this->assertTrue($doc->elementExists($xpath, $xmlFile));
$this->assertEquals('lowerRoman', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); $this->assertEquals('lowerRoman', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
} }
/**
* Parse ordered list start & numbering style
*/
public function testParseVerticalAlign()
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
// borders & backgrounds are here just for better visual comparison
$html = <<<HTML
<table width="100%">
<tr>
<td width="20%" style="border: 1px #666666 solid;">default</td>
<td width="20%" style="vertical-align: top; border: 1px #666666 solid;">top</td>
<td width="20%" style="vertical-align: middle; border: 1px #666666 solid;">middle</td>
<td width="20%" valign="bottom" style="border: 1px #666666 solid;">bottom</td>
<td bgcolor="#DDDDDD"><br/><br/><br/><br/><br/><br/><br/></td>
</tr>
</table>
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
// uncomment to see results
file_put_contents('./table_src.html', $html);
file_put_contents('./table_result_'.time().'.docx', file_get_contents( TestHelperDOCX::getFile() ) );
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:tcPr/w:vAlign';
$this->assertFalse($doc->elementExists($xpath));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:vAlign';
$this->assertTrue($doc->elementExists($xpath));
$this->assertEquals('top', $doc->getElement($xpath)->getAttribute('w:val'));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[3]/w:tcPr/w:vAlign';
$this->assertTrue($doc->elementExists($xpath));
$this->assertEquals('center', $doc->getElement($xpath)->getAttribute('w:val'));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[4]/w:tcPr/w:vAlign';
$this->assertTrue($doc->elementExists($xpath));
$this->assertEquals('bottom', $doc->getElement($xpath)->getAttribute('w:val'));
}
} }