For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

589 lines
23 KiB

  1. <?php
  2. /**
  3. * PHPExcel_Writer_Excel2007_Drawing
  4. *
  5. * Copyright (c) 2006 - 2015 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Writer_Excel2007
  23. * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart
  28. {
  29. /**
  30. * Write drawings to XML format
  31. *
  32. * @param PHPExcel_Worksheet $pWorksheet
  33. * @param int &$chartRef Chart ID
  34. * @param boolean $includeCharts Flag indicating if we should include drawing details for charts
  35. * @return string XML Output
  36. * @throws PHPExcel_Writer_Exception
  37. */
  38. public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = false)
  39. {
  40. // Create XML writer
  41. $objWriter = null;
  42. if ($this->getParentWriter()->getUseDiskCaching()) {
  43. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
  44. } else {
  45. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
  46. }
  47. // XML header
  48. $objWriter->startDocument('1.0', 'UTF-8', 'yes');
  49. // xdr:wsDr
  50. $objWriter->startElement('xdr:wsDr');
  51. $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
  52. $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
  53. // Loop through images and write drawings
  54. $i = 1;
  55. $iterator = $pWorksheet->getDrawingCollection()->getIterator();
  56. while ($iterator->valid()) {
  57. $this->writeDrawing($objWriter, $iterator->current(), $i);
  58. $iterator->next();
  59. ++$i;
  60. }
  61. if ($includeCharts) {
  62. $chartCount = $pWorksheet->getChartCount();
  63. // Loop through charts and write the chart position
  64. if ($chartCount > 0) {
  65. for ($c = 0; $c < $chartCount; ++$c) {
  66. $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i);
  67. }
  68. }
  69. }
  70. $objWriter->endElement();
  71. // Return
  72. return $objWriter->getData();
  73. }
  74. /**
  75. * Write drawings to XML format
  76. *
  77. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  78. * @param PHPExcel_Chart $pChart
  79. * @param int $pRelationId
  80. * @throws PHPExcel_Writer_Exception
  81. */
  82. public function writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1)
  83. {
  84. $tl = $pChart->getTopLeftPosition();
  85. $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']);
  86. $br = $pChart->getBottomRightPosition();
  87. $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']);
  88. $objWriter->startElement('xdr:twoCellAnchor');
  89. $objWriter->startElement('xdr:from');
  90. $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1);
  91. $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset']));
  92. $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);
  93. $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset']));
  94. $objWriter->endElement();
  95. $objWriter->startElement('xdr:to');
  96. $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1);
  97. $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset']));
  98. $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);
  99. $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset']));
  100. $objWriter->endElement();
  101. $objWriter->startElement('xdr:graphicFrame');
  102. $objWriter->writeAttribute('macro', '');
  103. $objWriter->startElement('xdr:nvGraphicFramePr');
  104. $objWriter->startElement('xdr:cNvPr');
  105. $objWriter->writeAttribute('name', 'Chart '.$pRelationId);
  106. $objWriter->writeAttribute('id', 1025 * $pRelationId);
  107. $objWriter->endElement();
  108. $objWriter->startElement('xdr:cNvGraphicFramePr');
  109. $objWriter->startElement('a:graphicFrameLocks');
  110. $objWriter->endElement();
  111. $objWriter->endElement();
  112. $objWriter->endElement();
  113. $objWriter->startElement('xdr:xfrm');
  114. $objWriter->startElement('a:off');
  115. $objWriter->writeAttribute('x', '0');
  116. $objWriter->writeAttribute('y', '0');
  117. $objWriter->endElement();
  118. $objWriter->startElement('a:ext');
  119. $objWriter->writeAttribute('cx', '0');
  120. $objWriter->writeAttribute('cy', '0');
  121. $objWriter->endElement();
  122. $objWriter->endElement();
  123. $objWriter->startElement('a:graphic');
  124. $objWriter->startElement('a:graphicData');
  125. $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
  126. $objWriter->startElement('c:chart');
  127. $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
  128. $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
  129. $objWriter->writeAttribute('r:id', 'rId'.$pRelationId);
  130. $objWriter->endElement();
  131. $objWriter->endElement();
  132. $objWriter->endElement();
  133. $objWriter->endElement();
  134. $objWriter->startElement('xdr:clientData');
  135. $objWriter->endElement();
  136. $objWriter->endElement();
  137. }
  138. /**
  139. * Write drawings to XML format
  140. *
  141. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  142. * @param PHPExcel_Worksheet_BaseDrawing $pDrawing
  143. * @param int $pRelationId
  144. * @throws PHPExcel_Writer_Exception
  145. */
  146. public function writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1)
  147. {
  148. if ($pRelationId >= 0) {
  149. // xdr:oneCellAnchor
  150. $objWriter->startElement('xdr:oneCellAnchor');
  151. // Image location
  152. $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates());
  153. $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]);
  154. // xdr:from
  155. $objWriter->startElement('xdr:from');
  156. $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
  157. $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX()));
  158. $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
  159. $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY()));
  160. $objWriter->endElement();
  161. // xdr:ext
  162. $objWriter->startElement('xdr:ext');
  163. $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));
  164. $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));
  165. $objWriter->endElement();
  166. // xdr:pic
  167. $objWriter->startElement('xdr:pic');
  168. // xdr:nvPicPr
  169. $objWriter->startElement('xdr:nvPicPr');
  170. // xdr:cNvPr
  171. $objWriter->startElement('xdr:cNvPr');
  172. $objWriter->writeAttribute('id', $pRelationId);
  173. $objWriter->writeAttribute('name', $pDrawing->getName());
  174. $objWriter->writeAttribute('descr', $pDrawing->getDescription());
  175. $objWriter->endElement();
  176. // xdr:cNvPicPr
  177. $objWriter->startElement('xdr:cNvPicPr');
  178. // a:picLocks
  179. $objWriter->startElement('a:picLocks');
  180. $objWriter->writeAttribute('noChangeAspect', '1');
  181. $objWriter->endElement();
  182. $objWriter->endElement();
  183. $objWriter->endElement();
  184. // xdr:blipFill
  185. $objWriter->startElement('xdr:blipFill');
  186. // a:blip
  187. $objWriter->startElement('a:blip');
  188. $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
  189. $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);
  190. $objWriter->endElement();
  191. // a:stretch
  192. $objWriter->startElement('a:stretch');
  193. $objWriter->writeElement('a:fillRect', null);
  194. $objWriter->endElement();
  195. $objWriter->endElement();
  196. // xdr:spPr
  197. $objWriter->startElement('xdr:spPr');
  198. // a:xfrm
  199. $objWriter->startElement('a:xfrm');
  200. $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation()));
  201. $objWriter->endElement();
  202. // a:prstGeom
  203. $objWriter->startElement('a:prstGeom');
  204. $objWriter->writeAttribute('prst', 'rect');
  205. // a:avLst
  206. $objWriter->writeElement('a:avLst', null);
  207. $objWriter->endElement();
  208. // // a:solidFill
  209. // $objWriter->startElement('a:solidFill');
  210. // // a:srgbClr
  211. // $objWriter->startElement('a:srgbClr');
  212. // $objWriter->writeAttribute('val', 'FFFFFF');
  213. ///* SHADE
  214. // // a:shade
  215. // $objWriter->startElement('a:shade');
  216. // $objWriter->writeAttribute('val', '85000');
  217. // $objWriter->endElement();
  218. //*/
  219. // $objWriter->endElement();
  220. // $objWriter->endElement();
  221. /*
  222. // a:ln
  223. $objWriter->startElement('a:ln');
  224. $objWriter->writeAttribute('w', '88900');
  225. $objWriter->writeAttribute('cap', 'sq');
  226. // a:solidFill
  227. $objWriter->startElement('a:solidFill');
  228. // a:srgbClr
  229. $objWriter->startElement('a:srgbClr');
  230. $objWriter->writeAttribute('val', 'FFFFFF');
  231. $objWriter->endElement();
  232. $objWriter->endElement();
  233. // a:miter
  234. $objWriter->startElement('a:miter');
  235. $objWriter->writeAttribute('lim', '800000');
  236. $objWriter->endElement();
  237. $objWriter->endElement();
  238. */
  239. if ($pDrawing->getShadow()->getVisible()) {
  240. // a:effectLst
  241. $objWriter->startElement('a:effectLst');
  242. // a:outerShdw
  243. $objWriter->startElement('a:outerShdw');
  244. $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));
  245. $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));
  246. $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));
  247. $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment());
  248. $objWriter->writeAttribute('rotWithShape', '0');
  249. // a:srgbClr
  250. $objWriter->startElement('a:srgbClr');
  251. $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB());
  252. // a:alpha
  253. $objWriter->startElement('a:alpha');
  254. $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000);
  255. $objWriter->endElement();
  256. $objWriter->endElement();
  257. $objWriter->endElement();
  258. $objWriter->endElement();
  259. }
  260. /*
  261. // a:scene3d
  262. $objWriter->startElement('a:scene3d');
  263. // a:camera
  264. $objWriter->startElement('a:camera');
  265. $objWriter->writeAttribute('prst', 'orthographicFront');
  266. $objWriter->endElement();
  267. // a:lightRig
  268. $objWriter->startElement('a:lightRig');
  269. $objWriter->writeAttribute('rig', 'twoPt');
  270. $objWriter->writeAttribute('dir', 't');
  271. // a:rot
  272. $objWriter->startElement('a:rot');
  273. $objWriter->writeAttribute('lat', '0');
  274. $objWriter->writeAttribute('lon', '0');
  275. $objWriter->writeAttribute('rev', '0');
  276. $objWriter->endElement();
  277. $objWriter->endElement();
  278. $objWriter->endElement();
  279. */
  280. /*
  281. // a:sp3d
  282. $objWriter->startElement('a:sp3d');
  283. // a:bevelT
  284. $objWriter->startElement('a:bevelT');
  285. $objWriter->writeAttribute('w', '25400');
  286. $objWriter->writeAttribute('h', '19050');
  287. $objWriter->endElement();
  288. // a:contourClr
  289. $objWriter->startElement('a:contourClr');
  290. // a:srgbClr
  291. $objWriter->startElement('a:srgbClr');
  292. $objWriter->writeAttribute('val', 'FFFFFF');
  293. $objWriter->endElement();
  294. $objWriter->endElement();
  295. $objWriter->endElement();
  296. */
  297. $objWriter->endElement();
  298. $objWriter->endElement();
  299. // xdr:clientData
  300. $objWriter->writeElement('xdr:clientData', null);
  301. $objWriter->endElement();
  302. } else {
  303. throw new PHPExcel_Writer_Exception("Invalid parameters passed.");
  304. }
  305. }
  306. /**
  307. * Write VML header/footer images to XML format
  308. *
  309. * @param PHPExcel_Worksheet $pWorksheet
  310. * @return string XML Output
  311. * @throws PHPExcel_Writer_Exception
  312. */
  313. public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null)
  314. {
  315. // Create XML writer
  316. $objWriter = null;
  317. if ($this->getParentWriter()->getUseDiskCaching()) {
  318. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
  319. } else {
  320. $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);
  321. }
  322. // XML header
  323. $objWriter->startDocument('1.0', 'UTF-8', 'yes');
  324. // Header/footer images
  325. $images = $pWorksheet->getHeaderFooter()->getImages();
  326. // xml
  327. $objWriter->startElement('xml');
  328. $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
  329. $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
  330. $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
  331. // o:shapelayout
  332. $objWriter->startElement('o:shapelayout');
  333. $objWriter->writeAttribute('v:ext', 'edit');
  334. // o:idmap
  335. $objWriter->startElement('o:idmap');
  336. $objWriter->writeAttribute('v:ext', 'edit');
  337. $objWriter->writeAttribute('data', '1');
  338. $objWriter->endElement();
  339. $objWriter->endElement();
  340. // v:shapetype
  341. $objWriter->startElement('v:shapetype');
  342. $objWriter->writeAttribute('id', '_x0000_t75');
  343. $objWriter->writeAttribute('coordsize', '21600,21600');
  344. $objWriter->writeAttribute('o:spt', '75');
  345. $objWriter->writeAttribute('o:preferrelative', 't');
  346. $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
  347. $objWriter->writeAttribute('filled', 'f');
  348. $objWriter->writeAttribute('stroked', 'f');
  349. // v:stroke
  350. $objWriter->startElement('v:stroke');
  351. $objWriter->writeAttribute('joinstyle', 'miter');
  352. $objWriter->endElement();
  353. // v:formulas
  354. $objWriter->startElement('v:formulas');
  355. // v:f
  356. $objWriter->startElement('v:f');
  357. $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
  358. $objWriter->endElement();
  359. // v:f
  360. $objWriter->startElement('v:f');
  361. $objWriter->writeAttribute('eqn', 'sum @0 1 0');
  362. $objWriter->endElement();
  363. // v:f
  364. $objWriter->startElement('v:f');
  365. $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
  366. $objWriter->endElement();
  367. // v:f
  368. $objWriter->startElement('v:f');
  369. $objWriter->writeAttribute('eqn', 'prod @2 1 2');
  370. $objWriter->endElement();
  371. // v:f
  372. $objWriter->startElement('v:f');
  373. $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
  374. $objWriter->endElement();
  375. // v:f
  376. $objWriter->startElement('v:f');
  377. $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
  378. $objWriter->endElement();
  379. // v:f
  380. $objWriter->startElement('v:f');
  381. $objWriter->writeAttribute('eqn', 'sum @0 0 1');
  382. $objWriter->endElement();
  383. // v:f
  384. $objWriter->startElement('v:f');
  385. $objWriter->writeAttribute('eqn', 'prod @6 1 2');
  386. $objWriter->endElement();
  387. // v:f
  388. $objWriter->startElement('v:f');
  389. $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
  390. $objWriter->endElement();
  391. // v:f
  392. $objWriter->startElement('v:f');
  393. $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
  394. $objWriter->endElement();
  395. // v:f
  396. $objWriter->startElement('v:f');
  397. $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
  398. $objWriter->endElement();
  399. // v:f
  400. $objWriter->startElement('v:f');
  401. $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
  402. $objWriter->endElement();
  403. $objWriter->endElement();
  404. // v:path
  405. $objWriter->startElement('v:path');
  406. $objWriter->writeAttribute('o:extrusionok', 'f');
  407. $objWriter->writeAttribute('gradientshapeok', 't');
  408. $objWriter->writeAttribute('o:connecttype', 'rect');
  409. $objWriter->endElement();
  410. // o:lock
  411. $objWriter->startElement('o:lock');
  412. $objWriter->writeAttribute('v:ext', 'edit');
  413. $objWriter->writeAttribute('aspectratio', 't');
  414. $objWriter->endElement();
  415. $objWriter->endElement();
  416. // Loop through images
  417. foreach ($images as $key => $value) {
  418. $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
  419. }
  420. $objWriter->endElement();
  421. // Return
  422. return $objWriter->getData();
  423. }
  424. /**
  425. * Write VML comment to XML format
  426. *
  427. * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer
  428. * @param string $pReference Reference
  429. * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image
  430. * @throws PHPExcel_Writer_Exception
  431. */
  432. private function writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null)
  433. {
  434. // Calculate object id
  435. preg_match('{(\d+)}', md5($pReference), $m);
  436. $id = 1500 + (substr($m[1], 0, 2) * 1);
  437. // Calculate offset
  438. $width = $pImage->getWidth();
  439. $height = $pImage->getHeight();
  440. $marginLeft = $pImage->getOffsetX();
  441. $marginTop = $pImage->getOffsetY();
  442. // v:shape
  443. $objWriter->startElement('v:shape');
  444. $objWriter->writeAttribute('id', $pReference);
  445. $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
  446. $objWriter->writeAttribute('type', '#_x0000_t75');
  447. $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
  448. // v:imagedata
  449. $objWriter->startElement('v:imagedata');
  450. $objWriter->writeAttribute('o:relid', 'rId' . $pReference);
  451. $objWriter->writeAttribute('o:title', $pImage->getName());
  452. $objWriter->endElement();
  453. // o:lock
  454. $objWriter->startElement('o:lock');
  455. $objWriter->writeAttribute('v:ext', 'edit');
  456. $objWriter->writeAttribute('rotation', 't');
  457. $objWriter->endElement();
  458. $objWriter->endElement();
  459. }
  460. /**
  461. * Get an array of all drawings
  462. *
  463. * @param PHPExcel $pPHPExcel
  464. * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel
  465. * @throws PHPExcel_Writer_Exception
  466. */
  467. public function allDrawings(PHPExcel $pPHPExcel = null)
  468. {
  469. // Get an array of all drawings
  470. $aDrawings = array();
  471. // Loop through PHPExcel
  472. $sheetCount = $pPHPExcel->getSheetCount();
  473. for ($i = 0; $i < $sheetCount; ++$i) {
  474. // Loop through images and add to array
  475. $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator();
  476. while ($iterator->valid()) {
  477. $aDrawings[] = $iterator->current();
  478. $iterator->next();
  479. }
  480. }
  481. return $aDrawings;
  482. }
  483. }