See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Worksheet; 4 5 use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; 6 use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; 7 use PhpOffice\PhpSpreadsheet\IComparable; 8 9 class BaseDrawing implements IComparable 10 { 11 const EDIT_AS_ABSOLUTE = 'absolute'; 12 const EDIT_AS_ONECELL = 'oneCell'; 13 const EDIT_AS_TWOCELL = 'twoCell'; 14 private const VALID_EDIT_AS = [ 15 self::EDIT_AS_ABSOLUTE, 16 self::EDIT_AS_ONECELL, 17 self::EDIT_AS_TWOCELL, 18 ]; 19 20 /** 21 * The editAs attribute, used only with two cell anchor. 22 * 23 * @var string 24 */ 25 protected $editAs = ''; 26 27 /** 28 * Image counter. 29 * 30 * @var int 31 */ 32 private static $imageCounter = 0; 33 34 /** 35 * Image index. 36 * 37 * @var int 38 */ 39 private $imageIndex = 0; 40 41 /** 42 * Name. 43 * 44 * @var string 45 */ 46 protected $name = ''; 47 48 /** 49 * Description. 50 * 51 * @var string 52 */ 53 protected $description = ''; 54 55 /** 56 * Worksheet. 57 * 58 * @var null|Worksheet 59 */ 60 protected $worksheet; 61 62 /** 63 * Coordinates. 64 * 65 * @var string 66 */ 67 protected $coordinates = 'A1'; 68 69 /** 70 * Offset X. 71 * 72 * @var int 73 */ 74 protected $offsetX = 0; 75 76 /** 77 * Offset Y. 78 * 79 * @var int 80 */ 81 protected $offsetY = 0; 82 83 /** 84 * Coordinates2. 85 * 86 * @var string 87 */ 88 protected $coordinates2 = ''; 89 90 /** 91 * Offset X2. 92 * 93 * @var int 94 */ 95 protected $offsetX2 = 0; 96 97 /** 98 * Offset Y2. 99 * 100 * @var int 101 */ 102 protected $offsetY2 = 0; 103 104 /** 105 * Width. 106 * 107 * @var int 108 */ 109 protected $width = 0; 110 111 /** 112 * Height. 113 * 114 * @var int 115 */ 116 protected $height = 0; 117 118 /** 119 * Pixel width of image. See $width for the size the Drawing will be in the sheet. 120 * 121 * @var int 122 */ 123 protected $imageWidth = 0; 124 125 /** 126 * Pixel width of image. See $height for the size the Drawing will be in the sheet. 127 * 128 * @var int 129 */ 130 protected $imageHeight = 0; 131 132 /** 133 * Proportional resize. 134 * 135 * @var bool 136 */ 137 protected $resizeProportional = true; 138 139 /** 140 * Rotation. 141 * 142 * @var int 143 */ 144 protected $rotation = 0; 145 146 /** 147 * Shadow. 148 * 149 * @var Drawing\Shadow 150 */ 151 protected $shadow; 152 153 /** 154 * Image hyperlink. 155 * 156 * @var null|Hyperlink 157 */ 158 private $hyperlink; 159 160 /** 161 * Image type. 162 * 163 * @var int 164 */ 165 protected $type = IMAGETYPE_UNKNOWN; 166 167 /** 168 * Create a new BaseDrawing. 169 */ 170 public function __construct() 171 { 172 // Initialise values 173 $this->setShadow(); 174 175 // Set image index 176 ++self::$imageCounter; 177 $this->imageIndex = self::$imageCounter; 178 } 179 180 public function getImageIndex(): int 181 { 182 return $this->imageIndex; 183 } 184 185 public function getName(): string 186 { 187 return $this->name; 188 } 189 190 public function setName(string $name): self 191 { 192 $this->name = $name; 193 194 return $this; 195 } 196 197 public function getDescription(): string 198 { 199 return $this->description; 200 } 201 202 public function setDescription(string $description): self 203 { 204 $this->description = $description; 205 206 return $this; 207 } 208 209 public function getWorksheet(): ?Worksheet 210 { 211 return $this->worksheet; 212 } 213 214 /** 215 * Set Worksheet. 216 * 217 * @param bool $overrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? 218 */ 219 public function setWorksheet(?Worksheet $worksheet = null, bool $overrideOld = false): self 220 { 221 if ($this->worksheet === null) { 222 // Add drawing to \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet 223 if ($worksheet !== null) { 224 $this->worksheet = $worksheet; 225 $this->worksheet->getCell($this->coordinates); 226 $this->worksheet->getDrawingCollection()->append($this); 227 } 228 } else { 229 if ($overrideOld) { 230 // Remove drawing from old \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet 231 $iterator = $this->worksheet->getDrawingCollection()->getIterator(); 232 233 while ($iterator->valid()) { 234 if ($iterator->current()->getHashCode() === $this->getHashCode()) { 235 $this->worksheet->getDrawingCollection()->offsetUnset($iterator->key()); 236 $this->worksheet = null; 237 238 break; 239 } 240 } 241 242 // Set new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet 243 $this->setWorksheet($worksheet); 244 } else { 245 throw new PhpSpreadsheetException('A Worksheet has already been assigned. Drawings can only exist on one \\PhpOffice\\PhpSpreadsheet\\Worksheet.'); 246 } 247 } 248 249 return $this; 250 } 251 252 public function getCoordinates(): string 253 { 254 return $this->coordinates; 255 } 256 257 public function setCoordinates(string $coordinates): self 258 { 259 $this->coordinates = $coordinates; 260 261 return $this; 262 } 263 264 public function getOffsetX(): int 265 { 266 return $this->offsetX; 267 } 268 269 public function setOffsetX(int $offsetX): self 270 { 271 $this->offsetX = $offsetX; 272 273 return $this; 274 } 275 276 public function getOffsetY(): int 277 { 278 return $this->offsetY; 279 } 280 281 public function setOffsetY(int $offsetY): self 282 { 283 $this->offsetY = $offsetY; 284 285 return $this; 286 } 287 288 public function getCoordinates2(): string 289 { 290 return $this->coordinates2; 291 } 292 293 public function setCoordinates2(string $coordinates2): self 294 { 295 $this->coordinates2 = $coordinates2; 296 297 return $this; 298 } 299 300 public function getOffsetX2(): int 301 { 302 return $this->offsetX2; 303 } 304 305 public function setOffsetX2(int $offsetX2): self 306 { 307 $this->offsetX2 = $offsetX2; 308 309 return $this; 310 } 311 312 public function getOffsetY2(): int 313 { 314 return $this->offsetY2; 315 } 316 317 public function setOffsetY2(int $offsetY2): self 318 { 319 $this->offsetY2 = $offsetY2; 320 321 return $this; 322 } 323 324 public function getWidth(): int 325 { 326 return $this->width; 327 } 328 329 public function setWidth(int $width): self 330 { 331 // Resize proportional? 332 if ($this->resizeProportional && $width != 0) { 333 $ratio = $this->height / ($this->width != 0 ? $this->width : 1); 334 $this->height = (int) round($ratio * $width); 335 } 336 337 // Set width 338 $this->width = $width; 339 340 return $this; 341 } 342 343 public function getHeight(): int 344 { 345 return $this->height; 346 } 347 348 public function setHeight(int $height): self 349 { 350 // Resize proportional? 351 if ($this->resizeProportional && $height != 0) { 352 $ratio = $this->width / ($this->height != 0 ? $this->height : 1); 353 $this->width = (int) round($ratio * $height); 354 } 355 356 // Set height 357 $this->height = $height; 358 359 return $this; 360 } 361 362 /** 363 * Set width and height with proportional resize. 364 * 365 * Example: 366 * <code> 367 * $objDrawing->setResizeProportional(true); 368 * $objDrawing->setWidthAndHeight(160,120); 369 * </code> 370 * 371 * @author Vincent@luo MSN:kele_100@hotmail.com 372 */ 373 public function setWidthAndHeight(int $width, int $height): self 374 { 375 $xratio = $width / ($this->width != 0 ? $this->width : 1); 376 $yratio = $height / ($this->height != 0 ? $this->height : 1); 377 if ($this->resizeProportional && !($width == 0 || $height == 0)) { 378 if (($xratio * $this->height) < $height) { 379 $this->height = (int) ceil($xratio * $this->height); 380 $this->width = $width; 381 } else { 382 $this->width = (int) ceil($yratio * $this->width); 383 $this->height = $height; 384 } 385 } else { 386 $this->width = $width; 387 $this->height = $height; 388 } 389 390 return $this; 391 } 392 393 public function getResizeProportional(): bool 394 { 395 return $this->resizeProportional; 396 } 397 398 public function setResizeProportional(bool $resizeProportional): self 399 { 400 $this->resizeProportional = $resizeProportional; 401 402 return $this; 403 } 404 405 public function getRotation(): int 406 { 407 return $this->rotation; 408 } 409 410 public function setRotation(int $rotation): self 411 { 412 $this->rotation = $rotation; 413 414 return $this; 415 } 416 417 public function getShadow(): Drawing\Shadow 418 { 419 return $this->shadow; 420 } 421 422 public function setShadow(?Drawing\Shadow $shadow = null): self 423 { 424 $this->shadow = $shadow ?? new Drawing\Shadow(); 425 426 return $this; 427 } 428 429 /** 430 * Get hash code. 431 * 432 * @return string Hash code 433 */ 434 public function getHashCode() 435 { 436 return md5( 437 $this->name . 438 $this->description . 439 (($this->worksheet === null) ? '' : $this->worksheet->getHashCode()) . 440 $this->coordinates . 441 $this->offsetX . 442 $this->offsetY . 443 $this->coordinates2 . 444 $this->offsetX2 . 445 $this->offsetY2 . 446 $this->width . 447 $this->height . 448 $this->rotation . 449 $this->shadow->getHashCode() . 450 __CLASS__ 451 ); 452 } 453 454 /** 455 * Implement PHP __clone to create a deep clone, not just a shallow copy. 456 */ 457 public function __clone() 458 { 459 $vars = get_object_vars($this); 460 foreach ($vars as $key => $value) { 461 if ($key == 'worksheet') { 462 $this->worksheet = null; 463 } elseif (is_object($value)) { 464 $this->$key = clone $value; 465 } else { 466 $this->$key = $value; 467 } 468 } 469 } 470 471 public function setHyperlink(?Hyperlink $hyperlink = null): void 472 { 473 $this->hyperlink = $hyperlink; 474 } 475 476 public function getHyperlink(): ?Hyperlink 477 { 478 return $this->hyperlink; 479 } 480 481 /** 482 * Set Fact Sizes and Type of Image. 483 */ 484 protected function setSizesAndType(string $path): void 485 { 486 if ($this->imageWidth === 0 && $this->imageHeight === 0 && $this->type === IMAGETYPE_UNKNOWN) { 487 $imageData = getimagesize($path); 488 489 if (is_array($imageData)) { 490 $this->imageWidth = $imageData[0]; 491 $this->imageHeight = $imageData[1]; 492 $this->type = $imageData[2]; 493 } 494 } 495 if ($this->width === 0 && $this->height === 0) { 496 $this->width = $this->imageWidth; 497 $this->height = $this->imageHeight; 498 } 499 } 500 501 /** 502 * Get Image Type. 503 */ 504 public function getType(): int 505 { 506 return $this->type; 507 } 508 509 public function getImageWidth(): int 510 { 511 return $this->imageWidth; 512 } 513 514 public function getImageHeight(): int 515 { 516 return $this->imageHeight; 517 } 518 519 public function getEditAs(): string 520 { 521 return $this->editAs; 522 } 523 524 public function setEditAs(string $editAs): self 525 { 526 $this->editAs = $editAs; 527 528 return $this; 529 } 530 531 public function validEditAs(): bool 532 { 533 return in_array($this->editAs, self::VALID_EDIT_AS, true); 534 } 535 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body