updated a couple packages (#1567)
[openemr.git] / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Writer / Xlsx / Drawing.php
bloba8bd8c04efdafe8d1280c221bebb02ed7af0ff29
1 <?php
3 namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
5 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
7 use PhpOffice\PhpSpreadsheet\Spreadsheet;
8 use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
9 use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
10 use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
12 class Drawing extends WriterPart
14 /**
15 * Write drawings to XML format.
17 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet
18 * @param bool $includeCharts Flag indicating if we should include drawing details for charts
20 * @throws WriterException
22 * @return string XML Output
24 public function writeDrawings(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $includeCharts = false)
26 // Create XML writer
27 $objWriter = null;
28 if ($this->getParentWriter()->getUseDiskCaching()) {
29 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
30 } else {
31 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
34 // XML header
35 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
37 // xdr:wsDr
38 $objWriter->startElement('xdr:wsDr');
39 $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
40 $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
42 // Loop through images and write drawings
43 $i = 1;
44 $iterator = $pWorksheet->getDrawingCollection()->getIterator();
45 while ($iterator->valid()) {
46 $this->writeDrawing($objWriter, $iterator->current(), $i);
48 $iterator->next();
49 ++$i;
52 if ($includeCharts) {
53 $chartCount = $pWorksheet->getChartCount();
54 // Loop through charts and write the chart position
55 if ($chartCount > 0) {
56 for ($c = 0; $c < $chartCount; ++$c) {
57 $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c + $i);
62 $objWriter->endElement();
64 // Return
65 return $objWriter->getData();
68 /**
69 * Write drawings to XML format.
71 * @param XMLWriter $objWriter XML Writer
72 * @param \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart
73 * @param int $pRelationId
75 public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1)
77 $tl = $pChart->getTopLeftPosition();
78 $tl['colRow'] = Coordinate::coordinateFromString($tl['cell']);
79 $br = $pChart->getBottomRightPosition();
80 $br['colRow'] = Coordinate::coordinateFromString($br['cell']);
82 $objWriter->startElement('xdr:twoCellAnchor');
84 $objWriter->startElement('xdr:from');
85 $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($tl['colRow'][0]) - 1);
86 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset']));
87 $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);
88 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset']));
89 $objWriter->endElement();
90 $objWriter->startElement('xdr:to');
91 $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($br['colRow'][0]) - 1);
92 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset']));
93 $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);
94 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset']));
95 $objWriter->endElement();
97 $objWriter->startElement('xdr:graphicFrame');
98 $objWriter->writeAttribute('macro', '');
99 $objWriter->startElement('xdr:nvGraphicFramePr');
100 $objWriter->startElement('xdr:cNvPr');
101 $objWriter->writeAttribute('name', 'Chart ' . $pRelationId);
102 $objWriter->writeAttribute('id', 1025 * $pRelationId);
103 $objWriter->endElement();
104 $objWriter->startElement('xdr:cNvGraphicFramePr');
105 $objWriter->startElement('a:graphicFrameLocks');
106 $objWriter->endElement();
107 $objWriter->endElement();
108 $objWriter->endElement();
110 $objWriter->startElement('xdr:xfrm');
111 $objWriter->startElement('a:off');
112 $objWriter->writeAttribute('x', '0');
113 $objWriter->writeAttribute('y', '0');
114 $objWriter->endElement();
115 $objWriter->startElement('a:ext');
116 $objWriter->writeAttribute('cx', '0');
117 $objWriter->writeAttribute('cy', '0');
118 $objWriter->endElement();
119 $objWriter->endElement();
121 $objWriter->startElement('a:graphic');
122 $objWriter->startElement('a:graphicData');
123 $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
124 $objWriter->startElement('c:chart');
125 $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
126 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
127 $objWriter->writeAttribute('r:id', 'rId' . $pRelationId);
128 $objWriter->endElement();
129 $objWriter->endElement();
130 $objWriter->endElement();
131 $objWriter->endElement();
133 $objWriter->startElement('xdr:clientData');
134 $objWriter->endElement();
136 $objWriter->endElement();
140 * Write drawings to XML format.
142 * @param XMLWriter $objWriter XML Writer
143 * @param BaseDrawing $pDrawing
144 * @param int $pRelationId
146 * @throws WriterException
148 public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1)
150 if ($pRelationId >= 0) {
151 // xdr:oneCellAnchor
152 $objWriter->startElement('xdr:oneCellAnchor');
153 // Image location
154 $aCoordinates = Coordinate::coordinateFromString($pDrawing->getCoordinates());
155 $aCoordinates[0] = Coordinate::columnIndexFromString($aCoordinates[0]);
157 // xdr:from
158 $objWriter->startElement('xdr:from');
159 $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
160 $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetX()));
161 $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
162 $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetY()));
163 $objWriter->endElement();
165 // xdr:ext
166 $objWriter->startElement('xdr:ext');
167 $objWriter->writeAttribute('cx', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getWidth()));
168 $objWriter->writeAttribute('cy', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getHeight()));
169 $objWriter->endElement();
171 // xdr:pic
172 $objWriter->startElement('xdr:pic');
174 // xdr:nvPicPr
175 $objWriter->startElement('xdr:nvPicPr');
177 // xdr:cNvPr
178 $objWriter->startElement('xdr:cNvPr');
179 $objWriter->writeAttribute('id', $pRelationId);
180 $objWriter->writeAttribute('name', $pDrawing->getName());
181 $objWriter->writeAttribute('descr', $pDrawing->getDescription());
182 $objWriter->endElement();
184 // xdr:cNvPicPr
185 $objWriter->startElement('xdr:cNvPicPr');
187 // a:picLocks
188 $objWriter->startElement('a:picLocks');
189 $objWriter->writeAttribute('noChangeAspect', '1');
190 $objWriter->endElement();
192 $objWriter->endElement();
194 $objWriter->endElement();
196 // xdr:blipFill
197 $objWriter->startElement('xdr:blipFill');
199 // a:blip
200 $objWriter->startElement('a:blip');
201 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
202 $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);
203 $objWriter->endElement();
205 // a:stretch
206 $objWriter->startElement('a:stretch');
207 $objWriter->writeElement('a:fillRect', null);
208 $objWriter->endElement();
210 $objWriter->endElement();
212 // xdr:spPr
213 $objWriter->startElement('xdr:spPr');
215 // a:xfrm
216 $objWriter->startElement('a:xfrm');
217 $objWriter->writeAttribute('rot', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getRotation()));
218 $objWriter->endElement();
220 // a:prstGeom
221 $objWriter->startElement('a:prstGeom');
222 $objWriter->writeAttribute('prst', 'rect');
224 // a:avLst
225 $objWriter->writeElement('a:avLst', null);
227 $objWriter->endElement();
229 if ($pDrawing->getShadow()->getVisible()) {
230 // a:effectLst
231 $objWriter->startElement('a:effectLst');
233 // a:outerShdw
234 $objWriter->startElement('a:outerShdw');
235 $objWriter->writeAttribute('blurRad', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));
236 $objWriter->writeAttribute('dist', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));
237 $objWriter->writeAttribute('dir', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));
238 $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment());
239 $objWriter->writeAttribute('rotWithShape', '0');
241 // a:srgbClr
242 $objWriter->startElement('a:srgbClr');
243 $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB());
245 // a:alpha
246 $objWriter->startElement('a:alpha');
247 $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000);
248 $objWriter->endElement();
250 $objWriter->endElement();
252 $objWriter->endElement();
254 $objWriter->endElement();
256 $objWriter->endElement();
258 $objWriter->endElement();
260 // xdr:clientData
261 $objWriter->writeElement('xdr:clientData', null);
263 $objWriter->endElement();
264 } else {
265 throw new WriterException('Invalid parameters passed.');
270 * Write VML header/footer images to XML format.
272 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet
274 * @throws WriterException
276 * @return string XML Output
278 public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
280 // Create XML writer
281 $objWriter = null;
282 if ($this->getParentWriter()->getUseDiskCaching()) {
283 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
284 } else {
285 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
288 // XML header
289 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
291 // Header/footer images
292 $images = $pWorksheet->getHeaderFooter()->getImages();
294 // xml
295 $objWriter->startElement('xml');
296 $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
297 $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
298 $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
300 // o:shapelayout
301 $objWriter->startElement('o:shapelayout');
302 $objWriter->writeAttribute('v:ext', 'edit');
304 // o:idmap
305 $objWriter->startElement('o:idmap');
306 $objWriter->writeAttribute('v:ext', 'edit');
307 $objWriter->writeAttribute('data', '1');
308 $objWriter->endElement();
310 $objWriter->endElement();
312 // v:shapetype
313 $objWriter->startElement('v:shapetype');
314 $objWriter->writeAttribute('id', '_x0000_t75');
315 $objWriter->writeAttribute('coordsize', '21600,21600');
316 $objWriter->writeAttribute('o:spt', '75');
317 $objWriter->writeAttribute('o:preferrelative', 't');
318 $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
319 $objWriter->writeAttribute('filled', 'f');
320 $objWriter->writeAttribute('stroked', 'f');
322 // v:stroke
323 $objWriter->startElement('v:stroke');
324 $objWriter->writeAttribute('joinstyle', 'miter');
325 $objWriter->endElement();
327 // v:formulas
328 $objWriter->startElement('v:formulas');
330 // v:f
331 $objWriter->startElement('v:f');
332 $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
333 $objWriter->endElement();
335 // v:f
336 $objWriter->startElement('v:f');
337 $objWriter->writeAttribute('eqn', 'sum @0 1 0');
338 $objWriter->endElement();
340 // v:f
341 $objWriter->startElement('v:f');
342 $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
343 $objWriter->endElement();
345 // v:f
346 $objWriter->startElement('v:f');
347 $objWriter->writeAttribute('eqn', 'prod @2 1 2');
348 $objWriter->endElement();
350 // v:f
351 $objWriter->startElement('v:f');
352 $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
353 $objWriter->endElement();
355 // v:f
356 $objWriter->startElement('v:f');
357 $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
358 $objWriter->endElement();
360 // v:f
361 $objWriter->startElement('v:f');
362 $objWriter->writeAttribute('eqn', 'sum @0 0 1');
363 $objWriter->endElement();
365 // v:f
366 $objWriter->startElement('v:f');
367 $objWriter->writeAttribute('eqn', 'prod @6 1 2');
368 $objWriter->endElement();
370 // v:f
371 $objWriter->startElement('v:f');
372 $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
373 $objWriter->endElement();
375 // v:f
376 $objWriter->startElement('v:f');
377 $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
378 $objWriter->endElement();
380 // v:f
381 $objWriter->startElement('v:f');
382 $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
383 $objWriter->endElement();
385 // v:f
386 $objWriter->startElement('v:f');
387 $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
388 $objWriter->endElement();
390 $objWriter->endElement();
392 // v:path
393 $objWriter->startElement('v:path');
394 $objWriter->writeAttribute('o:extrusionok', 'f');
395 $objWriter->writeAttribute('gradientshapeok', 't');
396 $objWriter->writeAttribute('o:connecttype', 'rect');
397 $objWriter->endElement();
399 // o:lock
400 $objWriter->startElement('o:lock');
401 $objWriter->writeAttribute('v:ext', 'edit');
402 $objWriter->writeAttribute('aspectratio', 't');
403 $objWriter->endElement();
405 $objWriter->endElement();
407 // Loop through images
408 foreach ($images as $key => $value) {
409 $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
412 $objWriter->endElement();
414 // Return
415 return $objWriter->getData();
419 * Write VML comment to XML format.
421 * @param XMLWriter $objWriter XML Writer
422 * @param string $pReference Reference
423 * @param HeaderFooterDrawing $pImage Image
425 private function writeVMLHeaderFooterImage(XMLWriter $objWriter, $pReference, HeaderFooterDrawing $pImage)
427 // Calculate object id
428 preg_match('{(\d+)}', md5($pReference), $m);
429 $id = 1500 + (substr($m[1], 0, 2) * 1);
431 // Calculate offset
432 $width = $pImage->getWidth();
433 $height = $pImage->getHeight();
434 $marginLeft = $pImage->getOffsetX();
435 $marginTop = $pImage->getOffsetY();
437 // v:shape
438 $objWriter->startElement('v:shape');
439 $objWriter->writeAttribute('id', $pReference);
440 $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
441 $objWriter->writeAttribute('type', '#_x0000_t75');
442 $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
444 // v:imagedata
445 $objWriter->startElement('v:imagedata');
446 $objWriter->writeAttribute('o:relid', 'rId' . $pReference);
447 $objWriter->writeAttribute('o:title', $pImage->getName());
448 $objWriter->endElement();
450 // o:lock
451 $objWriter->startElement('o:lock');
452 $objWriter->writeAttribute('v:ext', 'edit');
453 $objWriter->writeAttribute('textRotation', 't');
454 $objWriter->endElement();
456 $objWriter->endElement();
460 * Get an array of all drawings.
462 * @param Spreadsheet $spreadsheet
464 * @return \PhpOffice\PhpSpreadsheet\Worksheet\Drawing[] All drawings in PhpSpreadsheet
466 public function allDrawings(Spreadsheet $spreadsheet)
468 // Get an array of all drawings
469 $aDrawings = [];
471 // Loop through PhpSpreadsheet
472 $sheetCount = $spreadsheet->getSheetCount();
473 for ($i = 0; $i < $sheetCount; ++$i) {
474 // Loop through images and add to array
475 $iterator = $spreadsheet->getSheet($i)->getDrawingCollection()->getIterator();
476 while ($iterator->valid()) {
477 $aDrawings[] = $iterator->current();
479 $iterator->next();
483 return $aDrawings;