mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-14 20:16:34 +00:00
Html Writer Apply Rotation To Images
Fix #4875. If rotation is applied to a Drawing, Html Writer will now generate the appropriate Css. This will cause the image to be rotated for Html, Dompdf, and Mpdf; Tcpdf does not recognize the rotation Css.
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() !== '') {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Html;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class ImageRotateTest extends AbstractFunctional
|
||||
{
|
||||
public function testImageCopyXls(): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user