Drawing.php 22 KB

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