Add two cell anchor drawing (#2532)

* Add two cell anhor drawing.

* Add "Support for two cell anchor drawing of images." to CHANGELOG.md

* Add pull-request link to "Support for two cell anchor drawing of images." of CHANGELOG.md
This commit is contained in:
naotake51 2022-03-10 12:21:47 +09:00 committed by GitHub
parent ce5f91e6a1
commit 572f4e94bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 216 additions and 23 deletions

View File

@ -75,10 +75,11 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Full support of the above CF Rules for the Xlsx Reader and Writer; even when the file being loaded has CF rules listed in the `<extLst><ext><ConditionalFormattings>` element for the worksheet rather than the `<ConditionalFormatting>` element.
- Provision of a CellMatcher to identify if rules are matched for a cell, and which matching style will be applied.
- Improved documentation and examples, covering all supported CF rule types.
- Add support for one digit decimals (FORMAT_NUMBER_0, FORMAT_PERCENTAGE_0). [PR #2525](https://github.com/PHPOffice/PhpSpreadsheet/pull/2525)
- Initial work enabling Excel function implementations for handling arrays as arguments when used in "array formulae" [#2562](https://github.com/PHPOffice/PhpSpreadsheet/issues/2562)
- Enable most of the Date/Time functions to accept array arguments [#2573](https://github.com/PHPOffice/PhpSpreadsheet/issues/2573)
- Array ready functions - Text, Math/Trig, Statistical, Engineering and Logical [#2580](https://github.com/PHPOffice/PhpSpreadsheet/issues/2580)
- Add support for one digit decimals (FORMAT_NUMBER_0, FORMAT_PERCENTAGE_0). [PR #2525](https://github.com/PHPOffice/PhpSpreadsheet/pull/2525)
- Initial work enabling Excel function implementations for handling arrays as arguments when used in "array formulae" [#2562](https://github.com/PHPOffice/PhpSpreadsheet/issues/2562)
- Enable most of the Date/Time functions to accept array arguments [#2573](https://github.com/PHPOffice/PhpSpreadsheet/issues/2573)
- Array ready functions - Text, Math/Trig, Statistical, Engineering and Logical [#2580](https://github.com/PHPOffice/PhpSpreadsheet/issues/2580)
- Support for two cell anchor drawing of images. [#2532](https://github.com/PHPOffice/PhpSpreadsheet/pull/2532)
### Changed

View File

@ -5485,6 +5485,11 @@ parameters:
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php
-
message: "#^Parameter \\#1 \\$coordinates of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:indexesFromString\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
-
message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartByIndex\\(\\) expects string, int\\<0, max\\> given\\.$#"
count: 1
@ -5497,12 +5502,12 @@ parameters:
-
message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#"
count: 12
count: 20
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
count: 8
count: 10
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
-
@ -6009,4 +6014,3 @@ parameters:
message: "#^Cannot call method getExtension\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\BaseDrawing\\|null\\.$#"
count: 2
path: tests/PhpSpreadsheetTests/Writer/Xlsx/WmfTest.php

View File

@ -1340,6 +1340,12 @@ class Xlsx extends BaseReader
$objDrawing->setOffsetX(Drawing::EMUToPixels($twoCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
$objDrawing->setCoordinates2(Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1));
$objDrawing->setOffsetX2(Drawing::EMUToPixels($twoCellAnchor->to->colOff));
$objDrawing->setOffsetY2(Drawing::EMUToPixels($twoCellAnchor->to->rowOff));
$objDrawing->setResizeProportional(false);
if ($xfrm) {

View File

@ -64,6 +64,27 @@ class BaseDrawing implements IComparable
*/
protected $offsetY;
/**
* Coordinates2.
*
* @var null|string
*/
protected $coordinates2;
/**
* Offset X2.
*
* @var int
*/
protected $offsetX2;
/**
* Offset Y2.
*
* @var int
*/
protected $offsetY2;
/**
* Width.
*
@ -125,6 +146,9 @@ class BaseDrawing implements IComparable
$this->coordinates = 'A1';
$this->offsetX = 0;
$this->offsetY = 0;
$this->coordinates2 = null;
$this->offsetX2 = 0;
$this->offsetY2 = 0;
$this->width = 0;
$this->height = 0;
$this->resizeProportional = true;
@ -301,6 +325,78 @@ class BaseDrawing implements IComparable
return $this->offsetY;
}
/**
* Get Coordinates2.
*
* @return null|string
*/
public function getCoordinates2()
{
return $this->coordinates2;
}
/**
* Set Coordinates2.
*
* @param null|string $coordinates2 eg: 'A1'
*
* @return $this
*/
public function setCoordinates2($coordinates2)
{
$this->coordinates2 = $coordinates2;
return $this;
}
/**
* Get OffsetX2.
*
* @return int
*/
public function getOffsetX2()
{
return $this->offsetX2;
}
/**
* Set OffsetX2.
*
* @param int $offsetX2
*
* @return $this
*/
public function setOffsetX2($offsetX2)
{
$this->offsetX2 = $offsetX2;
return $this;
}
/**
* Get OffsetY2.
*
* @return int
*/
public function getOffsetY2()
{
return $this->offsetY2;
}
/**
* Set OffsetY2.
*
* @param int $offsetY2
*
* @return $this
*/
public function setOffsetY2($offsetY2)
{
$this->offsetY2 = $offsetY2;
return $this;
}
/**
* Set OffsetY.
*
@ -497,6 +593,9 @@ class BaseDrawing implements IComparable
$this->coordinates .
$this->offsetX .
$this->offsetY .
$this->coordinates2 .
$this->offsetX2 .
$this->offsetY2 .
$this->width .
$this->height .
$this->rotation .

View File

@ -153,6 +153,30 @@ class Drawing extends WriterPart
public function writeDrawing(XMLWriter $objWriter, BaseDrawing $drawing, $relationId = -1, $hlinkClickId = null): void
{
if ($relationId >= 0) {
$isTwoCellAnchor = $drawing->getCoordinates2() !== null;
if ($isTwoCellAnchor) {
// xdr:twoCellAnchor
$objWriter->startElement('xdr:twoCellAnchor');
// Image location
$aCoordinates = Coordinate::indexesFromString($drawing->getCoordinates());
$aCoordinates2 = Coordinate::indexesFromString($drawing->getCoordinates2());
// xdr:from
$objWriter->startElement('xdr:from');
$objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getOffsetX()));
$objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getOffsetY()));
$objWriter->endElement();
// xdr:to
$objWriter->startElement('xdr:to');
$objWriter->writeElement('xdr:col', $aCoordinates2[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getOffsetX2()));
$objWriter->writeElement('xdr:row', $aCoordinates2[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getOffsetY2()));
$objWriter->endElement();
} else {
// xdr:oneCellAnchor
$objWriter->startElement('xdr:oneCellAnchor');
// Image location
@ -171,6 +195,7 @@ class Drawing extends WriterPart
$objWriter->writeAttribute('cx', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getWidth()));
$objWriter->writeAttribute('cy', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getHeight()));
$objWriter->endElement();
}
// xdr:pic
$objWriter->startElement('xdr:pic');
@ -223,6 +248,12 @@ class Drawing extends WriterPart
// a:xfrm
$objWriter->startElement('a:xfrm');
$objWriter->writeAttribute('rot', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($drawing->getRotation()));
if ($isTwoCellAnchor) {
$objWriter->startElement('a:ext');
$objWriter->writeAttribute('cx', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getWidth()));
$objWriter->writeAttribute('cy', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($drawing->getHeight()));
$objWriter->endElement();
}
$objWriter->endElement();
// a:prstGeom

View File

@ -430,4 +430,56 @@ class DrawingsTest extends AbstractFunctional
self::assertNotNull($reloadedSpreadsheet);
}
/**
* Test save and load XLSX file with drawing image that coordinate is two cell anchor.
*/
public function testTwoCellAnchorDrawing(): void
{
$reader = new Xlsx();
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// Add gif image that coordinates is two cell anchor.
$drawing = new Drawing();
$drawing->setName('Green Square');
$drawing->setPath('tests/data/Writer/XLSX/green_square.gif');
self::assertEquals($drawing->getWidth(), 150);
self::assertEquals($drawing->getHeight(), 150);
$drawing->setCoordinates('A1');
$drawing->setOffsetX(30);
$drawing->setOffsetY(10);
$drawing->setCoordinates2('E8');
$drawing->setOffsetX2(-50);
$drawing->setOffsetY2(-20);
$drawing->setWorksheet($sheet);
// Write file
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$tempFileName = File::sysGetTempDir() . '/drawings_image_that_two_cell_anchor.xlsx';
$writer->save($tempFileName);
// Read new file
$reloadedSpreadsheet = $reader->load($tempFileName);
$sheet = $reloadedSpreadsheet->getActiveSheet();
// Check image coordinates.
$drawingCollection = $sheet->getDrawingCollection();
$drawing = $drawingCollection[0];
self::assertNotNull($drawing);
self::assertEquals($drawing->getWidth(), 150);
self::assertEquals($drawing->getHeight(), 150);
self::assertEquals($drawing->getCoordinates(), 'A1');
self::assertEquals($drawing->getOffsetX(), 30);
self::assertEquals($drawing->getOffsetY(), 10);
self::assertEquals($drawing->getCoordinates2(), 'E8');
self::assertEquals($drawing->getOffsetX2(), -50);
self::assertEquals($drawing->getOffsetY2(), -20);
self::assertEquals($drawing->getWorksheet(), $sheet);
unlink($tempFileName);
self::assertNotNull($reloadedSpreadsheet);
}
}