Skip to content

Commit 11663a9

Browse files
committed
Reader HTML: Support for differents size units for table
1 parent 639f396 commit 11663a9

File tree

3 files changed

+68
-42
lines changed

3 files changed

+68
-42
lines changed

docs/changes/1.x/1.4.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
- Writer ODText: Support for images inside a textRun by [@Progi1984](https://github.com/Progi1984) fixing [#2240](https://github.com/PHPOffice/PHPWord/issues/2240) in [#2668](https://github.com/PHPOffice/PHPWord/pull/2668)
1515
- Allow vAlign and vMerge on Style\Cell to be set to null by [@SpraxDev](https://github.com/SpraxDev) fixing [#2673](https://github.com/PHPOffice/PHPWord/issues/2673) in [#2676](https://github.com/PHPOffice/PHPWord/pull/2676)
16+
- Reader HTML: Support for differents size units for table by [@Progi1984](https://github.com/Progi1984) fixing [#2384](https://github.com/PHPOffice/PHPWord/issues/2384), [#2701](https://github.com/PHPOffice/PHPWord/issues/2701) in [#2725](https://github.com/PHPOffice/PHPWord/pull/2725)
1617

1718
### Miscellaneous
1819

src/PhpWord/Shared/Html.php

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,21 @@ protected static function parseInlineStyle($node, $styles = [])
128128
break;
129129
case 'width':
130130
// tables, cells
131+
$val = $val === 'auto' ? '100%' : $val;
131132
if (false !== strpos($val, '%')) {
132133
// e.g. <table width="100%"> or <td width="50%">
133134
$styles['width'] = (int) $val * 50;
134135
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT;
135136
} else {
136137
// e.g. <table width="250> where "250" = 250px (always pixels)
137-
$styles['width'] = Converter::pixelToTwip($val);
138+
$styles['width'] = Converter::pixelToTwip(self::convertHtmlSize($val));
138139
$styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP;
139140
}
140141

141142
break;
142143
case 'cellspacing':
143144
// tables e.g. <table cellspacing="2">, where "2" = 2px (always pixels)
144-
$val = (int) $val . 'px';
145-
$styles['cellSpacing'] = Converter::cssToTwip($val);
145+
$styles['cellSpacing'] = Converter::pixelToTwip(self::convertHtmlSize($val));
146146

147147
break;
148148
case 'bgcolor':
@@ -902,36 +902,12 @@ protected static function parseImage($node, $element)
902902

903903
break;
904904
case 'width':
905-
$width = $attribute->value;
906-
907-
// pt
908-
if (false !== strpos($width, 'pt')) {
909-
$width = Converter::pointToPixel((float) str_replace('pt', '', $width));
910-
}
911-
912-
// px
913-
if (false !== strpos($width, 'px')) {
914-
$width = str_replace('px', '', $width);
915-
}
916-
917-
$style['width'] = $width;
905+
$style['width'] = self::convertHtmlSize($attribute->value);
918906
$style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX;
919907

920908
break;
921909
case 'height':
922-
$height = $attribute->value;
923-
924-
// pt
925-
if (false !== strpos($height, 'pt')) {
926-
$height = Converter::pointToPixel((float) str_replace('pt', '', $height));
927-
}
928-
929-
// px
930-
if (false !== strpos($height, 'px')) {
931-
$height = str_replace('px', '', $height);
932-
}
933-
934-
$style['height'] = $height;
910+
$style['height'] = self::convertHtmlSize($attribute->value);
935911
$style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX;
936912

937913
break;
@@ -1211,4 +1187,22 @@ private static function convertRgb(string $rgb): string
12111187

12121188
return trim($rgb, '# ');
12131189
}
1190+
1191+
/**
1192+
* Transform HTML sizes (pt, px) in pixels.
1193+
*/
1194+
protected static function convertHtmlSize(string $size): float
1195+
{
1196+
// pt
1197+
if (false !== strpos($size, 'pt')) {
1198+
return Converter::pointToPixel((float) str_replace('pt', '', $size));
1199+
}
1200+
1201+
// px
1202+
if (false !== strpos($size, 'px')) {
1203+
return (float) str_replace('px', '', $size);
1204+
}
1205+
1206+
return $size;
1207+
}
12141208
}

tests/PhpWordTests/Shared/HtmlTest.php

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use PhpOffice\PhpWord\Shared\Html;
2626
use PhpOffice\PhpWord\SimpleType\Jc;
2727
use PhpOffice\PhpWord\SimpleType\LineSpacingRule;
28+
use PhpOffice\PhpWord\SimpleType\TblWidth;
2829
use PhpOffice\PhpWord\Style\Paragraph;
2930
use PhpOffice\PhpWordTests\AbstractWebServerEmbedded;
3031
use PhpOffice\PhpWordTests\TestHelperDOCX;
@@ -156,11 +157,11 @@ public function testParseStyleTableClassName(): void
156157
}
157158

158159
/**
159-
* Test underline.
160+
* Test text-decoration style.
160161
*/
161-
public function testParseUnderline(): void
162+
public function testParseTextDecoration(): void
162163
{
163-
$html = '<u>test</u>';
164+
$html = '<span style="text-decoration: underline;">test</span>';
164165
$phpWord = new PhpWord();
165166
$section = $phpWord->addSection();
166167
Html::addHtml($section, $html);
@@ -171,11 +172,11 @@ public function testParseUnderline(): void
171172
}
172173

173174
/**
174-
* Test text-decoration style.
175+
* Test underline.
175176
*/
176-
public function testParseTextDecoration(): void
177+
public function testParseUnderline(): void
177178
{
178-
$html = '<span style="text-decoration: underline;">test</span>';
179+
$html = '<u>test</u>';
179180
$phpWord = new PhpWord();
180181
$section = $phpWord->addSection();
181182
Html::addHtml($section, $html);
@@ -185,6 +186,25 @@ public function testParseTextDecoration(): void
185186
self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val'));
186187
}
187188

189+
/**
190+
* Test width.
191+
*
192+
* @dataProvider providerParseWidth
193+
*/
194+
public function testParseWidth(string $htmlSize, float $docxSize, string $docxUnit): void
195+
{
196+
$html = '<table width="' . $htmlSize . '"><tr><td>A</td></tr></table>';
197+
$phpWord = new PhpWord();
198+
$section = $phpWord->addSection();
199+
200+
Html::addHtml($section, $html);
201+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
202+
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblW';
203+
self::assertTrue($doc->elementExists($xpath));
204+
self::assertEquals($docxSize, $doc->getElement($xpath)->getAttribute('w:w'));
205+
self::assertEquals($docxUnit, $doc->getElement($xpath)->getAttribute('w:type'));
206+
}
207+
188208
/**
189209
* Test font-variant style.
190210
*/
@@ -461,31 +481,31 @@ public function testParseTableAndCellWidth(): void
461481
$xpath = '/w:document/w:body/w:tbl/w:tblGrid/w:gridCol';
462482
self::assertTrue($doc->elementExists($xpath));
463483
self::assertEquals(25 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
464-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
484+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
465485

466486
// <td style="width: 25%; ...
467487
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:tcW';
468488
self::assertTrue($doc->elementExists($xpath));
469489
self::assertEquals(25 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
470-
self::assertEquals('pct', $doc->getElement($xpath)->getAttribute('w:type'));
490+
self::assertEquals(TblWidth::PERCENT, $doc->getElement($xpath)->getAttribute('w:type'));
471491

472492
// <table width="400" .. 400px = 6000 twips (400 / 96 * 1440)
473493
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr/w:tc/w:tcPr/w:tcW';
474494
self::assertTrue($doc->elementExists($xpath));
475495
self::assertEquals(6000, $doc->getElement($xpath)->getAttribute('w:w'));
476-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
496+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
477497

478498
// <th style="width: 50pt; .. 50pt = 750 twips (50 / 72 * 1440)
479499
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:tcW';
480500
self::assertTrue($doc->elementExists($xpath));
481501
self::assertEquals(1000, $doc->getElement($xpath)->getAttribute('w:w'));
482-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
502+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
483503

484504
// <th width="300" .. 300px = 4500 twips (300 / 96 * 1440)
485505
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tbl/w:tr[3]/w:tc/w:tcPr/w:tcW';
486506
self::assertTrue($doc->elementExists($xpath));
487507
self::assertEquals(4500, $doc->getElement($xpath)->getAttribute('w:w'));
488-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
508+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
489509
}
490510

491511
/**
@@ -599,7 +619,7 @@ public function testParseTableCellspacingRowBgColor(): void
599619
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
600620
self::assertTrue($doc->elementExists($xpath));
601621
self::assertEquals(3 * 15, $doc->getElement($xpath)->getAttribute('w:w'));
602-
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
622+
self::assertEquals(TblWidth::TWIP, $doc->getElement($xpath)->getAttribute('w:type'));
603623

604624
$xpath = '/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:shd';
605625
self::assertTrue($doc->elementExists($xpath));
@@ -632,7 +652,7 @@ public function testParseTableStyleAttributeInlineStyle(): void
632652
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblW';
633653
self::assertTrue($doc->elementExists($xpath));
634654
self::assertEquals(100 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
635-
self::assertEquals('pct', $doc->getElement($xpath)->getAttribute('w:type'));
655+
self::assertEquals(TblWidth::PERCENT, $doc->getElement($xpath)->getAttribute('w:type'));
636656

637657
$xpath = '/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:shd';
638658
self::assertTrue($doc->elementExists($xpath));
@@ -1225,4 +1245,15 @@ public function testDontDecodeAlreadyEncodedDoubleQuotes(): void
12251245
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
12261246
self::assertIsObject($doc);
12271247
}
1248+
1249+
public static function providerParseWidth(): array
1250+
{
1251+
return [
1252+
['auto', 5000, TblWidth::PERCENT],
1253+
['100%', 5000, TblWidth::PERCENT],
1254+
['200pt', 3999.999999999999, TblWidth::TWIP],
1255+
['300px', 4500, TblWidth::TWIP],
1256+
['400', 6000, TblWidth::TWIP],
1257+
];
1258+
}
12281259
}

0 commit comments

Comments
 (0)