ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Drawing.php
Go to the documentation of this file.
1 <?php
2 
4 
11 
12 class 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()) {
26  $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
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()) {
289  $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
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 }
getSheet($pIndex)
Get sheet by index.
if(!array_key_exists('StateId', $_REQUEST)) $id
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
getDiskCachingDirectory()
Get disk caching directory.
Definition: BaseWriter.php:92
writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId=-1)
Write drawings to XML format.
Definition: Drawing.php:84
writeVMLHeaderFooterImage(XMLWriter $objWriter, $pReference, HeaderFooterDrawing $pImage)
Write VML comment to XML format.
Definition: Drawing.php:431
static indexesFromString(string $coordinates)
Get indexes from a string coordinates.
Definition: Coordinate.php:52
$i
Definition: disco.tpl.php:19
getUseDiskCaching()
Get use disk caching where possible?
Definition: BaseWriter.php:72
allDrawings(Spreadsheet $spreadsheet)
Get an array of all drawings.
Definition: Drawing.php:470
$key
Definition: croninfo.php:18
writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId)
Definition: Drawing.php:493