ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Drawing.php
Go to the documentation of this file.
1<?php
2
4
11
12class Drawing extends WriterPart
13{
21 public function writeDrawings(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $includeCharts = false)
22 {
23 // Create XML writer
24 $objWriter = null;
25 if ($this->getParentWriter()->getUseDiskCaching()) {
27 } else {
28 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
29 }
30
31 // XML header
32 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
33
34 // xdr:wsDr
35 $objWriter->startElement('xdr:wsDr');
36 $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
37 $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
38
39 // Loop through images and write drawings
40 $i = 1;
41 $iterator = $pWorksheet->getDrawingCollection()->getIterator();
42 while ($iterator->valid()) {
44 $pDrawing = $iterator->current();
45 $pRelationId = $i;
46 $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i;
47
48 $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId);
49
50 $iterator->next();
51 ++$i;
52 }
53
54 if ($includeCharts) {
55 $chartCount = $pWorksheet->getChartCount();
56 // Loop through charts and write the chart position
57 if ($chartCount > 0) {
58 for ($c = 0; $c < $chartCount; ++$c) {
59 $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c + $i);
60 }
61 }
62 }
63
64 // unparsed AlternateContent
65 $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
66 if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'])) {
67 foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) {
68 $objWriter->writeRaw($drawingAlternateContent);
69 }
70 }
71
72 $objWriter->endElement();
73
74 // Return
75 return $objWriter->getData();
76 }
77
84 public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1): void
85 {
86 $tl = $pChart->getTopLeftPosition();
87 $tlColRow = Coordinate::indexesFromString($tl['cell']);
88 $br = $pChart->getBottomRightPosition();
89 $brColRow = Coordinate::indexesFromString($br['cell']);
90
91 $objWriter->startElement('xdr:twoCellAnchor');
92
93 $objWriter->startElement('xdr:from');
94 $objWriter->writeElement('xdr:col', $tlColRow[0] - 1);
95 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset']));
96 $objWriter->writeElement('xdr:row', $tlColRow[1] - 1);
97 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset']));
98 $objWriter->endElement();
99 $objWriter->startElement('xdr:to');
100 $objWriter->writeElement('xdr:col', $brColRow[0] - 1);
101 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset']));
102 $objWriter->writeElement('xdr:row', $brColRow[1] - 1);
103 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset']));
104 $objWriter->endElement();
105
106 $objWriter->startElement('xdr:graphicFrame');
107 $objWriter->writeAttribute('macro', '');
108 $objWriter->startElement('xdr:nvGraphicFramePr');
109 $objWriter->startElement('xdr:cNvPr');
110 $objWriter->writeAttribute('name', 'Chart ' . $pRelationId);
111 $objWriter->writeAttribute('id', 1025 * $pRelationId);
112 $objWriter->endElement();
113 $objWriter->startElement('xdr:cNvGraphicFramePr');
114 $objWriter->startElement('a:graphicFrameLocks');
115 $objWriter->endElement();
116 $objWriter->endElement();
117 $objWriter->endElement();
118
119 $objWriter->startElement('xdr:xfrm');
120 $objWriter->startElement('a:off');
121 $objWriter->writeAttribute('x', '0');
122 $objWriter->writeAttribute('y', '0');
123 $objWriter->endElement();
124 $objWriter->startElement('a:ext');
125 $objWriter->writeAttribute('cx', '0');
126 $objWriter->writeAttribute('cy', '0');
127 $objWriter->endElement();
128 $objWriter->endElement();
129
130 $objWriter->startElement('a:graphic');
131 $objWriter->startElement('a:graphicData');
132 $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
133 $objWriter->startElement('c:chart');
134 $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
135 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
136 $objWriter->writeAttribute('r:id', 'rId' . $pRelationId);
137 $objWriter->endElement();
138 $objWriter->endElement();
139 $objWriter->endElement();
140 $objWriter->endElement();
141
142 $objWriter->startElement('xdr:clientData');
143 $objWriter->endElement();
144
145 $objWriter->endElement();
146 }
147
155 public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1, $hlinkClickId = null): void
156 {
157 if ($pRelationId >= 0) {
158 // xdr:oneCellAnchor
159 $objWriter->startElement('xdr:oneCellAnchor');
160 // Image location
161 $aCoordinates = Coordinate::indexesFromString($pDrawing->getCoordinates());
162
163 // xdr:from
164 $objWriter->startElement('xdr:from');
165 $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
166 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetX()));
167 $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
168 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetY()));
169 $objWriter->endElement();
170
171 // xdr:ext
172 $objWriter->startElement('xdr:ext');
173 $objWriter->writeAttribute('cx', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getWidth()));
174 $objWriter->writeAttribute('cy', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getHeight()));
175 $objWriter->endElement();
176
177 // xdr:pic
178 $objWriter->startElement('xdr:pic');
179
180 // xdr:nvPicPr
181 $objWriter->startElement('xdr:nvPicPr');
182
183 // xdr:cNvPr
184 $objWriter->startElement('xdr:cNvPr');
185 $objWriter->writeAttribute('id', $pRelationId);
186 $objWriter->writeAttribute('name', $pDrawing->getName());
187 $objWriter->writeAttribute('descr', $pDrawing->getDescription());
188
189 //a:hlinkClick
190 $this->writeHyperLinkDrawing($objWriter, $hlinkClickId);
191
192 $objWriter->endElement();
193
194 // xdr:cNvPicPr
195 $objWriter->startElement('xdr:cNvPicPr');
196
197 // a:picLocks
198 $objWriter->startElement('a:picLocks');
199 $objWriter->writeAttribute('noChangeAspect', '1');
200 $objWriter->endElement();
201
202 $objWriter->endElement();
203
204 $objWriter->endElement();
205
206 // xdr:blipFill
207 $objWriter->startElement('xdr:blipFill');
208
209 // a:blip
210 $objWriter->startElement('a:blip');
211 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
212 $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);
213 $objWriter->endElement();
214
215 // a:stretch
216 $objWriter->startElement('a:stretch');
217 $objWriter->writeElement('a:fillRect', null);
218 $objWriter->endElement();
219
220 $objWriter->endElement();
221
222 // xdr:spPr
223 $objWriter->startElement('xdr:spPr');
224
225 // a:xfrm
226 $objWriter->startElement('a:xfrm');
227 $objWriter->writeAttribute('rot', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getRotation()));
228 $objWriter->endElement();
229
230 // a:prstGeom
231 $objWriter->startElement('a:prstGeom');
232 $objWriter->writeAttribute('prst', 'rect');
233
234 // a:avLst
235 $objWriter->writeElement('a:avLst', null);
236
237 $objWriter->endElement();
238
239 if ($pDrawing->getShadow()->getVisible()) {
240 // a:effectLst
241 $objWriter->startElement('a:effectLst');
242
243 // a:outerShdw
244 $objWriter->startElement('a:outerShdw');
245 $objWriter->writeAttribute('blurRad', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));
246 $objWriter->writeAttribute('dist', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));
247 $objWriter->writeAttribute('dir', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));
248 $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment());
249 $objWriter->writeAttribute('rotWithShape', '0');
250
251 // a:srgbClr
252 $objWriter->startElement('a:srgbClr');
253 $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB());
254
255 // a:alpha
256 $objWriter->startElement('a:alpha');
257 $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000);
258 $objWriter->endElement();
259
260 $objWriter->endElement();
261
262 $objWriter->endElement();
263
264 $objWriter->endElement();
265 }
266 $objWriter->endElement();
267
268 $objWriter->endElement();
269
270 // xdr:clientData
271 $objWriter->writeElement('xdr:clientData', null);
272
273 $objWriter->endElement();
274 } else {
275 throw new WriterException('Invalid parameters passed.');
276 }
277 }
278
284 public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
285 {
286 // Create XML writer
287 $objWriter = null;
288 if ($this->getParentWriter()->getUseDiskCaching()) {
290 } else {
291 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
292 }
293
294 // XML header
295 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
296
297 // Header/footer images
298 $images = $pWorksheet->getHeaderFooter()->getImages();
299
300 // xml
301 $objWriter->startElement('xml');
302 $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
303 $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
304 $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
305
306 // o:shapelayout
307 $objWriter->startElement('o:shapelayout');
308 $objWriter->writeAttribute('v:ext', 'edit');
309
310 // o:idmap
311 $objWriter->startElement('o:idmap');
312 $objWriter->writeAttribute('v:ext', 'edit');
313 $objWriter->writeAttribute('data', '1');
314 $objWriter->endElement();
315
316 $objWriter->endElement();
317
318 // v:shapetype
319 $objWriter->startElement('v:shapetype');
320 $objWriter->writeAttribute('id', '_x0000_t75');
321 $objWriter->writeAttribute('coordsize', '21600,21600');
322 $objWriter->writeAttribute('o:spt', '75');
323 $objWriter->writeAttribute('o:preferrelative', 't');
324 $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
325 $objWriter->writeAttribute('filled', 'f');
326 $objWriter->writeAttribute('stroked', 'f');
327
328 // v:stroke
329 $objWriter->startElement('v:stroke');
330 $objWriter->writeAttribute('joinstyle', 'miter');
331 $objWriter->endElement();
332
333 // v:formulas
334 $objWriter->startElement('v:formulas');
335
336 // v:f
337 $objWriter->startElement('v:f');
338 $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
339 $objWriter->endElement();
340
341 // v:f
342 $objWriter->startElement('v:f');
343 $objWriter->writeAttribute('eqn', 'sum @0 1 0');
344 $objWriter->endElement();
345
346 // v:f
347 $objWriter->startElement('v:f');
348 $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
349 $objWriter->endElement();
350
351 // v:f
352 $objWriter->startElement('v:f');
353 $objWriter->writeAttribute('eqn', 'prod @2 1 2');
354 $objWriter->endElement();
355
356 // v:f
357 $objWriter->startElement('v:f');
358 $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
359 $objWriter->endElement();
360
361 // v:f
362 $objWriter->startElement('v:f');
363 $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
364 $objWriter->endElement();
365
366 // v:f
367 $objWriter->startElement('v:f');
368 $objWriter->writeAttribute('eqn', 'sum @0 0 1');
369 $objWriter->endElement();
370
371 // v:f
372 $objWriter->startElement('v:f');
373 $objWriter->writeAttribute('eqn', 'prod @6 1 2');
374 $objWriter->endElement();
375
376 // v:f
377 $objWriter->startElement('v:f');
378 $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
379 $objWriter->endElement();
380
381 // v:f
382 $objWriter->startElement('v:f');
383 $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
384 $objWriter->endElement();
385
386 // v:f
387 $objWriter->startElement('v:f');
388 $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
389 $objWriter->endElement();
390
391 // v:f
392 $objWriter->startElement('v:f');
393 $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
394 $objWriter->endElement();
395
396 $objWriter->endElement();
397
398 // v:path
399 $objWriter->startElement('v:path');
400 $objWriter->writeAttribute('o:extrusionok', 'f');
401 $objWriter->writeAttribute('gradientshapeok', 't');
402 $objWriter->writeAttribute('o:connecttype', 'rect');
403 $objWriter->endElement();
404
405 // o:lock
406 $objWriter->startElement('o:lock');
407 $objWriter->writeAttribute('v:ext', 'edit');
408 $objWriter->writeAttribute('aspectratio', 't');
409 $objWriter->endElement();
410
411 $objWriter->endElement();
412
413 // Loop through images
414 foreach ($images as $key => $value) {
415 $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
416 }
417
418 $objWriter->endElement();
419
420 // Return
421 return $objWriter->getData();
422 }
423
431 private function writeVMLHeaderFooterImage(XMLWriter $objWriter, $pReference, HeaderFooterDrawing $pImage): void
432 {
433 // Calculate object id
434 preg_match('{(\d+)}', md5($pReference), $m);
435 $id = 1500 + ((int) substr($m[1], 0, 2) * 1);
436
437 // Calculate offset
438 $width = $pImage->getWidth();
439 $height = $pImage->getHeight();
440 $marginLeft = $pImage->getOffsetX();
441 $marginTop = $pImage->getOffsetY();
442
443 // v:shape
444 $objWriter->startElement('v:shape');
445 $objWriter->writeAttribute('id', $pReference);
446 $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
447 $objWriter->writeAttribute('type', '#_x0000_t75');
448 $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
449
450 // v:imagedata
451 $objWriter->startElement('v:imagedata');
452 $objWriter->writeAttribute('o:relid', 'rId' . $pReference);
453 $objWriter->writeAttribute('o:title', $pImage->getName());
454 $objWriter->endElement();
455
456 // o:lock
457 $objWriter->startElement('o:lock');
458 $objWriter->writeAttribute('v:ext', 'edit');
459 $objWriter->writeAttribute('textRotation', 't');
460 $objWriter->endElement();
461
462 $objWriter->endElement();
463 }
464
470 public function allDrawings(Spreadsheet $spreadsheet)
471 {
472 // Get an array of all drawings
473 $aDrawings = [];
474
475 // Loop through PhpSpreadsheet
476 $sheetCount = $spreadsheet->getSheetCount();
477 for ($i = 0; $i < $sheetCount; ++$i) {
478 // Loop through images and add to array
479 $iterator = $spreadsheet->getSheet($i)->getDrawingCollection()->getIterator();
480 while ($iterator->valid()) {
481 $aDrawings[] = $iterator->current();
482
483 $iterator->next();
484 }
485 }
486
487 return $aDrawings;
488 }
489
493 private function writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId): void
494 {
495 if ($hlinkClickId === null) {
496 return;
497 }
498
499 $objWriter->startElement('a:hlinkClick');
500 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
501 $objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId);
502 $objWriter->endElement();
503 }
504}
An exception for terminatinating execution or to throw for unit testing.
Helper class to manipulate cell coordinates.
Definition: Coordinate.php:15
static indexesFromString(string $coordinates)
Get indexes from a string coordinates.
Definition: Coordinate.php:52
const STORAGE_MEMORY
Temporary storage method.
Definition: XMLWriter.php:10
getSheet($pIndex)
Get sheet by index.
getDiskCachingDirectory()
Get disk caching directory.
Definition: BaseWriter.php:92
getUseDiskCaching()
Get use disk caching where possible?
Definition: BaseWriter.php:72
writeVMLHeaderFooterImage(XMLWriter $objWriter, $pReference, HeaderFooterDrawing $pImage)
Write VML comment to XML format.
Definition: Drawing.php:431
allDrawings(Spreadsheet $spreadsheet)
Get an array of all drawings.
Definition: Drawing.php:470
writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId)
Definition: Drawing.php:493
writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId=-1, $hlinkClickId=null)
Write drawings to XML format.
Definition: Drawing.php:155
writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
Write VML header/footer images to XML format.
Definition: Drawing.php:284
writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId=-1)
Write drawings to XML format.
Definition: Drawing.php:84
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
if(!array_key_exists('StateId', $_REQUEST)) $id