parent
							
								
									b05d07a365
								
							
						
					
					
						commit
						17d4a54666
					
				| @ -9,8 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). | ||||
| 
 | ||||
| ### Added | ||||
| 
 | ||||
| - Add excel function EXACT(value1, value2) support | ||||
| - Add excel function EXACT(value1, value2) support - [595](https://github.com/PHPOffice/PhpSpreadsheet/pull/595) | ||||
| - Support workbook view attributes for Xlsx format - [#523](https://github.com/PHPOffice/PhpSpreadsheet/issues/523) | ||||
| - Read and write hyperlink for drawing image - [#490](https://github.com/PHPOffice/PhpSpreadsheet/pull/490) | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
|  | ||||
| @ -750,6 +750,24 @@ | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td style="padding-left: 1em;">Drawing hyperlink</td> | ||||
|         <td></td> | ||||
|         <td style="text-align: center; color: green;">✔</td>  | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td style="text-align: center; color: green;">✔</td>  | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td></td> | ||||
|         <td>$drawing->getHyperlink()->getUrl()</td> | ||||
|         <td>$drawing->setHyperlink()->setUrl($url)</td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td><strong>Cell Formatting</strong></td> | ||||
|         <td></td> | ||||
|  | ||||
							
								
								
									
										54
									
								
								samples/Reader/20_Reader_worksheet_hyperlink_image.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								samples/Reader/20_Reader_worksheet_hyperlink_image.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| <?php | ||||
| 
 | ||||
| use PhpOffice\PhpSpreadsheet\Spreadsheet; | ||||
| 
 | ||||
| require __DIR__ . '/../Header.php'; | ||||
| $inputFileType = 'Xlsx'; | ||||
| 
 | ||||
| $helper->log('Start'); | ||||
| 
 | ||||
| $spreadsheet = new Spreadsheet(); | ||||
| 
 | ||||
| $aSheet = $spreadsheet->getActiveSheet(); | ||||
| 
 | ||||
| $gdImage = @imagecreatetruecolor(120, 20); | ||||
| $textColor = imagecolorallocate($gdImage, 255, 255, 255); | ||||
| imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor); | ||||
| 
 | ||||
| $baseUrl = 'https://phpspreadsheet.readthedocs.io/'; | ||||
| 
 | ||||
| $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing(); | ||||
| $drawing->setName('In-Memory image 1'); | ||||
| $drawing->setDescription('In-Memory image 1'); | ||||
| $drawing->setCoordinates('A1'); | ||||
| $drawing->setImageResource($gdImage); | ||||
| $drawing->setRenderingFunction( | ||||
|     \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG | ||||
| ); | ||||
| $drawing->setMimeType(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_DEFAULT); | ||||
| $drawing->setHeight(36); | ||||
| $helper->log('Write image'); | ||||
| 
 | ||||
| $hyperLink = new \PhpOffice\PhpSpreadsheet\Cell\Hyperlink($baseUrl, 'test image'); | ||||
| $drawing->setHyperlink($hyperLink); | ||||
| $helper->log('Write link: ' . $baseUrl); | ||||
| 
 | ||||
| $drawing->setWorksheet($aSheet); | ||||
| 
 | ||||
| $filename = tempnam(\PhpOffice\PhpSpreadsheet\Shared\File::sysGetTempDir(), 'phpspreadsheet-test'); | ||||
| 
 | ||||
| $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, $inputFileType); | ||||
| $writer->save($filename); | ||||
| 
 | ||||
| $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); | ||||
| 
 | ||||
| $reloadedSpreadsheet = $reader->load($filename); | ||||
| unlink($filename); | ||||
| 
 | ||||
| $helper->log('reloaded Spreadsheet'); | ||||
| 
 | ||||
| foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) { | ||||
|     $helper->log('Read link: ' . $pDrawing->getHyperlink()->getUrl()); | ||||
| } | ||||
| 
 | ||||
| $helper->log('end'); | ||||
| @ -89,6 +89,14 @@ class Hyperlink | ||||
|         return strpos($this->url, 'sheet://') !== false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getTypeHyperlink() | ||||
|     { | ||||
|         return $this->isInternal() ? '' : 'External'; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get hash code. | ||||
|      * | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| namespace PhpOffice\PhpSpreadsheet\Reader; | ||||
| 
 | ||||
| use PhpOffice\PhpSpreadsheet\Cell\Coordinate; | ||||
| use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; | ||||
| use PhpOffice\PhpSpreadsheet\Document\Properties; | ||||
| use PhpOffice\PhpSpreadsheet\NamedRange; | ||||
| use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart; | ||||
| @ -1669,9 +1670,12 @@ class Xlsx extends BaseReader | ||||
|                                             Settings::getLibXmlLoaderOptions() | ||||
|                                         ); | ||||
|                                         $images = []; | ||||
| 
 | ||||
|                                         $hyperlinks = []; | ||||
|                                         if ($relsDrawing && $relsDrawing->Relationship) { | ||||
|                                             foreach ($relsDrawing->Relationship as $ele) { | ||||
|                                                 if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink') { | ||||
|                                                     $hyperlinks[(string) $ele['Id']] = (string) $ele['Target']; | ||||
|                                                 } | ||||
|                                                 if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { | ||||
|                                                     $images[(string) $ele['Id']] = self::dirAdd($fileDrawing, $ele['Target']); | ||||
|                                                 } elseif ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart') { | ||||
| @ -1699,6 +1703,9 @@ class Xlsx extends BaseReader | ||||
|                                                     $xfrm = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm; | ||||
|                                                     /** @var SimpleXMLElement $outerShdw */ | ||||
|                                                     $outerShdw = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw; | ||||
|                                                     /** @var \SimpleXMLElement $hlinkClick */ | ||||
|                                                     $hlinkClick = $oneCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; | ||||
| 
 | ||||
|                                                     $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); | ||||
|                                                     $objDrawing->setName((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name')); | ||||
|                                                     $objDrawing->setDescription((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr')); | ||||
| @ -1729,6 +1736,9 @@ class Xlsx extends BaseReader | ||||
|                                                         $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val')); | ||||
|                                                         $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000); | ||||
|                                                     } | ||||
| 
 | ||||
|                                                     $this->readHyperLinkDrawing($objDrawing, $oneCellAnchor, $hyperlinks); | ||||
| 
 | ||||
|                                                     $objDrawing->setWorksheet($docSheet); | ||||
|                                                 } else { | ||||
|                                                     //    ? Can charts be positioned with a oneCellAnchor ?
 | ||||
| @ -1746,6 +1756,7 @@ class Xlsx extends BaseReader | ||||
|                                                     $blip = $twoCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip; | ||||
|                                                     $xfrm = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm; | ||||
|                                                     $outerShdw = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw; | ||||
|                                                     $hlinkClick = $twoCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; | ||||
|                                                     $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); | ||||
|                                                     $objDrawing->setName((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name')); | ||||
|                                                     $objDrawing->setDescription((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr')); | ||||
| @ -1777,6 +1788,9 @@ class Xlsx extends BaseReader | ||||
|                                                         $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val')); | ||||
|                                                         $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000); | ||||
|                                                     } | ||||
| 
 | ||||
|                                                     $this->readHyperLinkDrawing($objDrawing, $twoCellAnchor, $hyperlinks); | ||||
| 
 | ||||
|                                                     $objDrawing->setWorksheet($docSheet); | ||||
|                                                 } elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) { | ||||
|                                                     $fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1); | ||||
| @ -2427,6 +2441,27 @@ class Xlsx extends BaseReader | ||||
|         return $value === 'true' || $value === 'TRUE'; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $objDrawing | ||||
|      * @param \SimpleXMLElement $cellAnchor | ||||
|      * @param array $hyperlinks | ||||
|      */ | ||||
|     private function readHyperLinkDrawing($objDrawing, $cellAnchor, $hyperlinks) | ||||
|     { | ||||
|         $hlinkClick = $cellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; | ||||
| 
 | ||||
|         if ($hlinkClick->count() === 0) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         $hlinkId = (string) $hlinkClick->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships')['id']; | ||||
|         $hyperlink = new Hyperlink( | ||||
|             $hyperlinks[$hlinkId], | ||||
|             (string) self::getArrayItem($cellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name') | ||||
|         ); | ||||
|         $objDrawing->setHyperlink($hyperlink); | ||||
|     } | ||||
| 
 | ||||
|     private function readProtection(Spreadsheet $excel, SimpleXMLElement $xmlWorkbook) | ||||
|     { | ||||
|         if (!$xmlWorkbook->workbookProtection) { | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| namespace PhpOffice\PhpSpreadsheet\Worksheet; | ||||
| 
 | ||||
| use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; | ||||
| use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; | ||||
| use PhpOffice\PhpSpreadsheet\IComparable; | ||||
| 
 | ||||
| @ -98,6 +99,13 @@ class BaseDrawing implements IComparable | ||||
|      */ | ||||
|     protected $shadow; | ||||
| 
 | ||||
|     /** | ||||
|      * Image hyperlink. | ||||
|      * | ||||
|      * @var null|Hyperlink | ||||
|      */ | ||||
|     private $hyperlink; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new BaseDrawing. | ||||
|      */ | ||||
| @ -508,4 +516,20 @@ class BaseDrawing implements IComparable | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param null|Hyperlink $pHyperlink | ||||
|      */ | ||||
|     public function setHyperlink(Hyperlink $pHyperlink = null) | ||||
|     { | ||||
|         $this->hyperlink = $pHyperlink; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return null|Hyperlink | ||||
|      */ | ||||
|     public function getHyperlink() | ||||
|     { | ||||
|         return $this->hyperlink; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -43,7 +43,12 @@ class Drawing extends WriterPart | ||||
|         $i = 1; | ||||
|         $iterator = $pWorksheet->getDrawingCollection()->getIterator(); | ||||
|         while ($iterator->valid()) { | ||||
|             $this->writeDrawing($objWriter, $iterator->current(), $i); | ||||
|             /** @var BaseDrawing $pDrawing */ | ||||
|             $pDrawing = $iterator->current(); | ||||
|             $pRelationId = $i; | ||||
|             $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i; | ||||
| 
 | ||||
|             $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); | ||||
| 
 | ||||
|             $iterator->next(); | ||||
|             ++$i; | ||||
| @ -150,10 +155,11 @@ class Drawing extends WriterPart | ||||
|      * @param XMLWriter $objWriter XML Writer | ||||
|      * @param BaseDrawing $pDrawing | ||||
|      * @param int $pRelationId | ||||
|      * @param null|int $hlinkClickId | ||||
|      * | ||||
|      * @throws WriterException | ||||
|      */ | ||||
|     public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1) | ||||
|     public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1, $hlinkClickId = null) | ||||
|     { | ||||
|         if ($pRelationId >= 0) { | ||||
|             // xdr:oneCellAnchor
 | ||||
| @ -187,6 +193,10 @@ class Drawing extends WriterPart | ||||
|             $objWriter->writeAttribute('id', $pRelationId); | ||||
|             $objWriter->writeAttribute('name', $pDrawing->getName()); | ||||
|             $objWriter->writeAttribute('descr', $pDrawing->getDescription()); | ||||
| 
 | ||||
|             //a:hlinkClick
 | ||||
|             $this->writeHyperLinkDrawing($objWriter, $hlinkClickId); | ||||
| 
 | ||||
|             $objWriter->endElement(); | ||||
| 
 | ||||
|             // xdr:cNvPicPr
 | ||||
| @ -490,4 +500,20 @@ class Drawing extends WriterPart | ||||
| 
 | ||||
|         return $aDrawings; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param XMLWriter $objWriter | ||||
|      * @param null|int $hlinkClickId | ||||
|      */ | ||||
|     private function writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId) | ||||
|     { | ||||
|         if ($hlinkClickId === null) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         $objWriter->startElement('a:hlinkClick'); | ||||
|         $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); | ||||
|         $objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId); | ||||
|         $objWriter->endElement(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -329,12 +329,16 @@ class Rels extends WriterPart | ||||
|             if ($iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing | ||||
|                 || $iterator->current() instanceof MemoryDrawing) { | ||||
|                 // Write relationship for image drawing
 | ||||
|                 /** @var \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing */ | ||||
|                 $drawing = $iterator->current(); | ||||
|                 $this->writeRelationship( | ||||
|                     $objWriter, | ||||
|                     $i, | ||||
|                     'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', | ||||
|                     '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) | ||||
|                     '../media/' . str_replace(' ', '', $drawing->getIndexedFilename()) | ||||
|                 ); | ||||
| 
 | ||||
|                 $i = $this->writeDrawingHyperLink($objWriter, $drawing, $i); | ||||
|             } | ||||
| 
 | ||||
|             $iterator->next(); | ||||
| @ -432,4 +436,31 @@ class Rels extends WriterPart | ||||
|             throw new WriterException('Invalid parameters passed.'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param $objWriter | ||||
|      * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing | ||||
|      * @param $i | ||||
|      * | ||||
|      * @throws WriterException | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     private function writeDrawingHyperLink($objWriter, $drawing, $i) | ||||
|     { | ||||
|         if ($drawing->getHyperlink() === null) { | ||||
|             return $i; | ||||
|         } | ||||
| 
 | ||||
|         ++$i; | ||||
|         $this->writeRelationship( | ||||
|             $objWriter, | ||||
|             $i, | ||||
|             'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', | ||||
|             $drawing->getHyperlink()->getUrl(), | ||||
|             $drawing->getHyperlink()->getTypeHyperlink() | ||||
|         ); | ||||
| 
 | ||||
|         return $i; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,51 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Created by PhpStorm. | ||||
|  * User: yuzhakov | ||||
|  * Date: 08.05.18 | ||||
|  * Time: 12:00. | ||||
|  */ | ||||
| 
 | ||||
| namespace PhpOffice\PhpSpreadsheetTests\Functional; | ||||
| 
 | ||||
| use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; | ||||
| use PhpOffice\PhpSpreadsheet\Spreadsheet; | ||||
| use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; | ||||
| 
 | ||||
| class DrawingImageHyperlinkTest extends AbstractFunctional | ||||
| { | ||||
|     /** | ||||
|      * @throws \PhpOffice\PhpSpreadsheet\Exception | ||||
|      */ | ||||
|     public function testDrawingImageHyperlinkTest() | ||||
|     { | ||||
|         $baseUrl = 'https://github.com/PHPOffice/PhpSpreadsheet'; | ||||
|         $spreadsheet = new Spreadsheet(); | ||||
| 
 | ||||
|         $aSheet = $spreadsheet->getActiveSheet(); | ||||
| 
 | ||||
|         $gdImage = @imagecreatetruecolor(120, 20); | ||||
|         $textColor = imagecolorallocate($gdImage, 255, 255, 255); | ||||
|         imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor); | ||||
| 
 | ||||
|         $drawing = new MemoryDrawing(); | ||||
|         $drawing->setName('In-Memory image 1'); | ||||
|         $drawing->setDescription('In-Memory image 1'); | ||||
|         $drawing->setCoordinates('A1'); | ||||
|         $drawing->setImageResource($gdImage); | ||||
|         $drawing->setRenderingFunction( | ||||
|             MemoryDrawing::RENDERING_JPEG | ||||
|         ); | ||||
|         $drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT); | ||||
|         $drawing->setHeight(36); | ||||
|         $hyperLink = new Hyperlink($baseUrl, 'test image'); | ||||
|         $drawing->setHyperlink($hyperLink); | ||||
|         $drawing->setWorksheet($aSheet); | ||||
| 
 | ||||
|         $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); | ||||
| 
 | ||||
|         foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) { | ||||
|             self::assertEquals('https://github.com/PHPOffice/PhpSpreadsheet', $pDrawing->getHyperlink()->getUrl(), 'functional test drawing hyperlink'); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 yuzhakov
						yuzhakov