Skip to content

Commit 9428552

Browse files
authored
Add editAs Property for 2-cell Anchor Drawings (#2674)
* Add editAs Property for 2-cell Anchor Drawings This change builds on PR #2532 (@naotake51 as PR #2532), using ideas from PR #2237 (@AdamGaskins), which has had changes requested for several months. It covers a lot of the same ground as 2532. In Excel, two-cell anchor drawings can be edited as "twocell", "onecell", or "absolute". This PR adds support for those options, with a sample file that demonstrates the difference in addition to unit tests. Several other tests are added to improve the spotty coverage for Drawings. There have been several other tickets referencing two cell anchors, including issue #1159 and PR #1160 (@sgarwood, who also added support for editAs), PR #643, and issue #126, all now closed but not necessarily entirely resolved. I will try to ensure that those tickets are addressed with this one. And, in trying to make sure 1160 is covered, I stumbled upon a bug. If you use the same image resource to create two+ memory drawings, the MemoryDrawing destructor for the first will cause the rest to generate a very long warning message. This is not a problem for Php8+, only for Php7-. I have suppressed the message in the MemoryDrawing constructor. 1160 went stale due to an unresolved test error, but I don't think this was the problem. At any rate, its test works now. * Scrutinizer It reported 1 minor issue (fixed normally), and 2 major. One is fixed with a kludge. The other is a case where Scrutinizer's analysis is just wrong, and I can't figure out a kludge. But I was able to add an annotation (the first time I've managed to get one past phpcs/php-cs-fixer). We'll see.
1 parent a8e179d commit 9428552

File tree

8 files changed

+475
-353
lines changed

8 files changed

+475
-353
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4220,26 +4220,6 @@ parameters:
42204220
count: 1
42214221
path: src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php
42224222

4223-
-
4224-
message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
4225-
count: 1
4226-
path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
4227-
4228-
-
4229-
message: "#^Cannot call method getDrawingCollection\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
4230-
count: 1
4231-
path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
4232-
4233-
-
4234-
message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
4235-
count: 1
4236-
path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
4237-
4238-
-
4239-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\BaseDrawing\\:\\:\\$shadow \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Drawing\\\\Shadow\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Drawing\\\\Shadow\\|null\\.$#"
4240-
count: 1
4241-
path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
4242-
42434223
-
42444224
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator\\:\\:adjustForExistingOnlyRange\\(\\) has no return type specified\\.$#"
42454225
count: 1
@@ -5250,36 +5230,6 @@ parameters:
52505230
count: 2
52515231
path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php
52525232

5253-
-
5254-
message: "#^Parameter \\#1 \\$coordinates of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:indexesFromString\\(\\) expects string, string\\|null given\\.$#"
5255-
count: 1
5256-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5257-
5258-
-
5259-
message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartByIndex\\(\\) expects string, int\\<0, max\\> given\\.$#"
5260-
count: 1
5261-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5262-
5263-
-
5264-
message: "#^Parameter \\#2 \\$chart of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Drawing\\:\\:writeChart\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\|false given\\.$#"
5265-
count: 1
5266-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5267-
5268-
-
5269-
message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#"
5270-
count: 20
5271-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5272-
5273-
-
5274-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
5275-
count: 10
5276-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5277-
5278-
-
5279-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#"
5280-
count: 1
5281-
path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
5282-
52835233
-
52845234
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$relationship with no type specified\\.$#"
52855235
count: 1
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
// Create new Spreadsheet object
4+
use PhpOffice\PhpSpreadsheet\Helper\Dimension;
5+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
6+
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
7+
8+
require __DIR__ . '/../Header.php';
9+
10+
$helper->log('Create new Spreadsheet object');
11+
$spreadsheet = new Spreadsheet();
12+
$sheet = $spreadsheet->getActiveSheet();
13+
$sheet->getCell('A1')->setValue('twocell');
14+
$sheet->getCell('A2')->setValue('twocell');
15+
$sheet->getCell('A3')->setValue('onecell');
16+
$sheet->getCell('A6')->setValue('absolute');
17+
18+
// Add a drawing to the worksheet
19+
$helper->log('Add a drawing to the worksheet two-cell anchor not resized');
20+
$drawing = new Drawing();
21+
$drawing->setName('PhpSpreadsheet');
22+
$drawing->setDescription('PhpSpreadsheet');
23+
$drawing->setPath(__DIR__ . '/../images/PhpSpreadsheet_logo.png');
24+
// anchor type will be two-cell because Coordinates2 is set
25+
//$drawing->setAnchorType(Drawing::ANCHORTYPE_TWOCELL);
26+
$drawing->setCoordinates('B1');
27+
$drawing->setCoordinates2('B1');
28+
$drawing->setOffsetX2($drawing->getImageWidth());
29+
$drawing->setOffsetY2($drawing->getImageHeight());
30+
$drawing->setWorksheet($spreadsheet->getActiveSheet());
31+
32+
// Add a drawing to the worksheet
33+
$helper->log('Add a drawing to the worksheet two-cell anchor resized');
34+
$drawing2 = new Drawing();
35+
$drawing2->setName('PhpSpreadsheet');
36+
$drawing2->setDescription('PhpSpreadsheet');
37+
$drawing2->setPath(__DIR__ . '/../images/PhpSpreadsheet_logo.png');
38+
// anchor type will be two-cell because Coordinates2 is set
39+
//$drawing->setAnchorType(Drawing::ANCHORTYPE_TWOCELL);
40+
$drawing2->setCoordinates('C2');
41+
$drawing2->setCoordinates2('C2');
42+
$drawing2->setOffsetX2($drawing->getImageWidth());
43+
$drawing2->setOffsetY2($drawing->getImageHeight());
44+
$drawing2->setWorksheet($spreadsheet->getActiveSheet());
45+
46+
$spreadsheet->getActiveSheet()->getColumnDimension('C')->setWidth($drawing->getImageWidth(), Dimension::UOM_PIXELS);
47+
$spreadsheet->getActiveSheet()->getRowDimension(2)->setRowHeight($drawing->getImageHeight(), Dimension::UOM_PIXELS);
48+
49+
// Add a drawing to the worksheet one cell anchor
50+
$helper->log('Add a drawing to the worksheet one-cell anchor');
51+
$drawing3 = new Drawing();
52+
$drawing3->setName('PhpSpreadsheet');
53+
$drawing3->setDescription('PhpSpreadsheet');
54+
$drawing3->setPath(__DIR__ . '/../images/PhpSpreadsheet_logo.png');
55+
// anchor type will be one-cell because Coordinates2 is not set
56+
//$drawing->setAnchorType(Drawing::ANCHORTYPE_ONECELL);
57+
$drawing3->setCoordinates('D3');
58+
$drawing3->setWorksheet($spreadsheet->getActiveSheet());
59+
60+
// Add a drawing to the worksheet
61+
$helper->log('Add a drawing to the worksheet two-cell anchor resized absolute');
62+
$drawing4 = new Drawing();
63+
$drawing4->setName('PhpSpreadsheet');
64+
$drawing4->setDescription('PhpSpreadsheet');
65+
$drawing4->setPath(__DIR__ . '/../images/PhpSpreadsheet_logo.png');
66+
// anchor type will be two-cell because Coordinates2 is set
67+
//$drawing->setAnchorType(Drawing::ANCHORTYPE_TWOCELL);
68+
$drawing4->setCoordinates('C6');
69+
$drawing4->setCoordinates2('C6');
70+
$drawing4->setOffsetX2($drawing->getImageWidth());
71+
$drawing4->setOffsetY2($drawing->getImageHeight());
72+
$drawing4->setWorksheet($spreadsheet->getActiveSheet());
73+
$drawing4->setEditAs(Drawing::EDIT_AS_ABSOLUTE);
74+
75+
//$spreadsheet->getActiveSheet()->getColumnDimension('C')->setWidth($drawing->getImageWidth(), Dimension::UOM_PIXELS);
76+
$spreadsheet->getActiveSheet()->getRowDimension(6)->setRowHeight($drawing->getImageHeight(), Dimension::UOM_PIXELS);
77+
78+
$helper->write($spreadsheet, __FILE__, ['Xlsx']);

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,11 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
13151315
$outerShdw = $twoCellAnchor->pic->spPr->children(Namespaces::DRAWINGML)->effectLst->outerShdw;
13161316
$hlinkClick = $twoCellAnchor->pic->nvPicPr->cNvPr->children(Namespaces::DRAWINGML)->hlinkClick;
13171317
$objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
1318+
/** @scrutinizer ignore-call */
1319+
$editAs = $twoCellAnchor->attributes();
1320+
if (isset($editAs, $editAs['editAs'])) {
1321+
$objDrawing->setEditAs($editAs['editAs']);
1322+
}
13181323
$objDrawing->setName((string) self::getArrayItem(self::getAttributes($twoCellAnchor->pic->nvPicPr->cNvPr), 'name'));
13191324
$objDrawing->setDescription((string) self::getArrayItem(self::getAttributes($twoCellAnchor->pic->nvPicPr->cNvPr), 'descr'));
13201325
$embedImageKey = (string) self::getArrayItem(

0 commit comments

Comments
 (0)