diff --git a/src/PhpSpreadsheet/Reader/Html.php b/src/PhpSpreadsheet/Reader/Html.php index 00e856641..3c1579368 100644 --- a/src/PhpSpreadsheet/Reader/Html.php +++ b/src/PhpSpreadsheet/Reader/Html.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader; +use Composer\Pcre\Preg; use DOMAttr; use DOMDocument; use DOMElement; @@ -180,7 +181,7 @@ class Html extends BaseReader return false; } - $beginning = preg_replace(self::STARTS_WITH_BOM, '', $this->readBeginning()) ?? ''; + $beginning = Preg::replace(self::STARTS_WITH_BOM, '', $this->readBeginning()); $startWithTag = self::startsWithTag($beginning); $containsTags = self::containsTags($beginning); @@ -457,7 +458,7 @@ class Html extends BaseReader } if (isset($attributeArray['style'])) { $alignStyle = $attributeArray['style']; - if (preg_match('/\btext-align:\s*(left|right|center|justify)\b/', (string) $alignStyle, $matches) === 1) { + if (Preg::isMatch('/\btext-align:\s*(left|right|center|justify)\b/', (string) $alignStyle, $matches)) { $sheet->getComment($column . $row)->setAlignment($matches[1]); } } @@ -772,7 +773,7 @@ class Html extends BaseReader { foreach ($element->childNodes as $child) { if ($child instanceof DOMText) { - $domText = (string) preg_replace('/\s+/', ' ', trim($child->nodeValue ?? '')); + $domText = Preg::replace('/\s+/', ' ', trim($child->nodeValue ?? '')); if ($domText === "\u{a0}") { $domText = ''; } @@ -883,7 +884,7 @@ class Html extends BaseReader break; default: - if (preg_match('/^custom[.](bool|date|float|int|string)[.](.+)$/', $metaName, $matches) === 1) { + if (Preg::isMatch('/^custom[.](bool|date|float|int|string)[.](.+)$/', $metaName, $matches)) { match ($matches[1]) { 'bool' => $properties->setCustomProperty($matches[2], (bool) $metaContent, Properties::PROPERTY_TYPE_BOOLEAN), 'float' => $properties->setCustomProperty($matches[2], (float) $metaContent, Properties::PROPERTY_TYPE_FLOAT), @@ -910,13 +911,12 @@ class Html extends BaseReader /** @internal */ protected static function replaceNonAsciiIfNeeded(string $convert): ?string { - if (preg_match(self::STARTS_WITH_BOM, $convert) !== 1 && preg_match(self::DECLARES_CHARSET, $convert) !== 1) { + if (!Preg::isMatch(self::STARTS_WITH_BOM, $convert) && !Preg::isMatch(self::DECLARES_CHARSET, $convert)) { $lowend = "\u{80}"; $highend = "\u{10ffff}"; $regexp = "/[$lowend-$highend]/u"; - /** @var callable $callback */ - $callback = [self::class, 'replaceNonAscii']; - $convert = preg_replace_callback($regexp, $callback, $convert); + // use native preg because of "u" modifier + $convert = preg_replace_callback($regexp, self::replaceNonAscii(...), $convert); } return $convert; @@ -1274,6 +1274,11 @@ class Html extends BaseReader $drawing->setOpacity((int) ($opacity * 100000)); } } + /** @var string */ + $transform = $styleArray['transform'] ?? ''; + if (Preg::isMatch('/rotate[(](-?\d{1,3})deg[)]$/', $transform, $matches)) { + $drawing->setRotation((int) $matches[1]); + } } /** diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php index fdeacacb3..3678cf67b 100644 --- a/src/PhpSpreadsheet/Writer/Html.php +++ b/src/PhpSpreadsheet/Writer/Html.php @@ -758,6 +758,11 @@ class Html extends BaseWriter $opacity = "opacity:$opacityValue; "; } } + $rotationValue = $drawing->getRotation(); + if ($rotationValue !== 0) { + $rotation = "transform: rotate({$rotationValue}deg); "; + $opacity .= $rotation; + } $filedesc = $drawing->getDescription(); $filedesc = $filedesc ? htmlspecialchars($filedesc, ENT_QUOTES) : 'Embedded image'; if ($drawing instanceof Drawing && $drawing->getPath() !== '') { diff --git a/tests/PhpSpreadsheetTests/Writer/Html/ImageRotateTest.php b/tests/PhpSpreadsheetTests/Writer/Html/ImageRotateTest.php new file mode 100644 index 000000000..f8149245c --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Html/ImageRotateTest.php @@ -0,0 +1,38 @@ +getActiveSheet(); + + $drawing = new Drawing(); + $drawing->setName('Blue Square'); + $drawing->setDescription('Blue_Square'); + $drawing->setPath('samples/images/blue_square.png'); + $drawing->setCoordinates('C5'); + $drawing->setRotation(45); + $drawing->setWorksheet($sheet); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Html'); + $spreadsheet->disconnectWorksheets(); + + $rsheet = $reloadedSpreadsheet->getActiveSheet(); + $drawings = $rsheet->getDrawingCollection(); + self::assertCount(1, $drawings); + $drawing = $drawings[0]; + self::assertNotNull($drawing); + self::assertSame(45, $drawing->getRotation()); + + $reloadedSpreadsheet->disconnectWorksheets(); + } +}