Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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\Writer\Xlsx;
   4  
   5  use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
   6  use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
   7  use PhpOffice\PhpSpreadsheet\Spreadsheet;
   8  use PhpOffice\PhpSpreadsheet\Style\Alignment;
   9  use PhpOffice\PhpSpreadsheet\Style\Border;
  10  use PhpOffice\PhpSpreadsheet\Style\Borders;
  11  use PhpOffice\PhpSpreadsheet\Style\Conditional;
  12  use PhpOffice\PhpSpreadsheet\Style\Fill;
  13  use PhpOffice\PhpSpreadsheet\Style\Font;
  14  use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
  15  use PhpOffice\PhpSpreadsheet\Style\Protection;
  16  
  17  class Style extends WriterPart
  18  {
  19      /**
  20       * Write styles to XML format.
  21       *
  22       * @return string XML Output
  23       */
  24      public function writeStyles(Spreadsheet $spreadsheet)
  25      {
  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);
  32          }
  33  
  34          // XML header
  35          $objWriter->startDocument('1.0', 'UTF-8', 'yes');
  36  
  37          // styleSheet
  38          $objWriter->startElement('styleSheet');
  39          $objWriter->writeAttribute('xml:space', 'preserve');
  40          $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
  41  
  42          // numFmts
  43          $objWriter->startElement('numFmts');
  44          $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getNumFmtHashTable()->count());
  45  
  46          // numFmt
  47          for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) {
  48              $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i);
  49          }
  50  
  51          $objWriter->endElement();
  52  
  53          // fonts
  54          $objWriter->startElement('fonts');
  55          $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFontHashTable()->count());
  56  
  57          // font
  58          for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {
  59              $thisfont = $this->getParentWriter()->getFontHashTable()->getByIndex($i);
  60              if ($thisfont !== null) {
  61                  $this->writeFont($objWriter, $thisfont);
  62              }
  63          }
  64  
  65          $objWriter->endElement();
  66  
  67          // fills
  68          $objWriter->startElement('fills');
  69          $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getFillHashTable()->count());
  70  
  71          // fill
  72          for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) {
  73              $thisfill = $this->getParentWriter()->getFillHashTable()->getByIndex($i);
  74              if ($thisfill !== null) {
  75                  $this->writeFill($objWriter, $thisfill);
  76              }
  77          }
  78  
  79          $objWriter->endElement();
  80  
  81          // borders
  82          $objWriter->startElement('borders');
  83          $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getBordersHashTable()->count());
  84  
  85          // border
  86          for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) {
  87              $thisborder = $this->getParentWriter()->getBordersHashTable()->getByIndex($i);
  88              if ($thisborder !== null) {
  89                  $this->writeBorder($objWriter, $thisborder);
  90              }
  91          }
  92  
  93          $objWriter->endElement();
  94  
  95          // cellStyleXfs
  96          $objWriter->startElement('cellStyleXfs');
  97          $objWriter->writeAttribute('count', '1');
  98  
  99          // xf
 100          $objWriter->startElement('xf');
 101          $objWriter->writeAttribute('numFmtId', '0');
 102          $objWriter->writeAttribute('fontId', '0');
 103          $objWriter->writeAttribute('fillId', '0');
 104          $objWriter->writeAttribute('borderId', '0');
 105          $objWriter->endElement();
 106  
 107          $objWriter->endElement();
 108  
 109          // cellXfs
 110          $objWriter->startElement('cellXfs');
 111          $objWriter->writeAttribute('count', (string) count($spreadsheet->getCellXfCollection()));
 112  
 113          // xf
 114          foreach ($spreadsheet->getCellXfCollection() as $cellXf) {
 115              $this->writeCellStyleXf($objWriter, $cellXf, $spreadsheet);
 116          }
 117  
 118          $objWriter->endElement();
 119  
 120          // cellStyles
 121          $objWriter->startElement('cellStyles');
 122          $objWriter->writeAttribute('count', '1');
 123  
 124          // cellStyle
 125          $objWriter->startElement('cellStyle');
 126          $objWriter->writeAttribute('name', 'Normal');
 127          $objWriter->writeAttribute('xfId', '0');
 128          $objWriter->writeAttribute('builtinId', '0');
 129          $objWriter->endElement();
 130  
 131          $objWriter->endElement();
 132  
 133          // dxfs
 134          $objWriter->startElement('dxfs');
 135          $objWriter->writeAttribute('count', (string) $this->getParentWriter()->getStylesConditionalHashTable()->count());
 136  
 137          // dxf
 138          for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {
 139              $thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i);
 140              if ($thisstyle !== null) {
 141                  $this->writeCellStyleDxf($objWriter, $thisstyle->getStyle());
 142              }
 143          }
 144  
 145          $objWriter->endElement();
 146  
 147          // tableStyles
 148          $objWriter->startElement('tableStyles');
 149          $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9');
 150          $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1');
 151          $objWriter->endElement();
 152  
 153          $objWriter->endElement();
 154  
 155          // Return
 156          return $objWriter->getData();
 157      }
 158  
 159      /**
 160       * Write Fill.
 161       */
 162      private function writeFill(XMLWriter $objWriter, Fill $fill): void
 163      {
 164          // Check if this is a pattern type or gradient type
 165          if (
 166              $fill->getFillType() === Fill::FILL_GRADIENT_LINEAR ||
 167              $fill->getFillType() === Fill::FILL_GRADIENT_PATH
 168          ) {
 169              // Gradient fill
 170              $this->writeGradientFill($objWriter, $fill);
 171          } elseif ($fill->getFillType() !== null) {
 172              // Pattern fill
 173              $this->writePatternFill($objWriter, $fill);
 174          }
 175      }
 176  
 177      /**
 178       * Write Gradient Fill.
 179       */
 180      private function writeGradientFill(XMLWriter $objWriter, Fill $fill): void
 181      {
 182          // fill
 183          $objWriter->startElement('fill');
 184  
 185          // gradientFill
 186          $objWriter->startElement('gradientFill');
 187          $objWriter->writeAttribute('type', (string) $fill->getFillType());
 188          $objWriter->writeAttribute('degree', (string) $fill->getRotation());
 189  
 190          // stop
 191          $objWriter->startElement('stop');
 192          $objWriter->writeAttribute('position', '0');
 193  
 194          // color
 195          if ($fill->getStartColor()->getARGB() !== null) {
 196              $objWriter->startElement('color');
 197              $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB());
 198              $objWriter->endElement();
 199          }
 200  
 201          $objWriter->endElement();
 202  
 203          // stop
 204          $objWriter->startElement('stop');
 205          $objWriter->writeAttribute('position', '1');
 206  
 207          // color
 208          if ($fill->getEndColor()->getARGB() !== null) {
 209              $objWriter->startElement('color');
 210              $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB());
 211              $objWriter->endElement();
 212          }
 213  
 214          $objWriter->endElement();
 215  
 216          $objWriter->endElement();
 217  
 218          $objWriter->endElement();
 219      }
 220  
 221      private static function writePatternColors(Fill $fill): bool
 222      {
 223          if ($fill->getFillType() === Fill::FILL_NONE) {
 224              return false;
 225          }
 226  
 227          return $fill->getFillType() === Fill::FILL_SOLID || $fill->getColorsChanged();
 228      }
 229  
 230      /**
 231       * Write Pattern Fill.
 232       */
 233      private function writePatternFill(XMLWriter $objWriter, Fill $fill): void
 234      {
 235          // fill
 236          $objWriter->startElement('fill');
 237  
 238          // patternFill
 239          $objWriter->startElement('patternFill');
 240          $objWriter->writeAttribute('patternType', (string) $fill->getFillType());
 241  
 242          if (self::writePatternColors($fill)) {
 243              // fgColor
 244              if ($fill->getStartColor()->getARGB()) {
 245                  $objWriter->startElement('fgColor');
 246                  $objWriter->writeAttribute('rgb', $fill->getStartColor()->getARGB());
 247                  $objWriter->endElement();
 248              }
 249              // bgColor
 250              if ($fill->getEndColor()->getARGB()) {
 251                  $objWriter->startElement('bgColor');
 252                  $objWriter->writeAttribute('rgb', $fill->getEndColor()->getARGB());
 253                  $objWriter->endElement();
 254              }
 255          }
 256  
 257          $objWriter->endElement();
 258  
 259          $objWriter->endElement();
 260      }
 261  
 262      /**
 263       * Write Font.
 264       */
 265      private function writeFont(XMLWriter $objWriter, Font $font): void
 266      {
 267          // font
 268          $objWriter->startElement('font');
 269          //    Weird! The order of these elements actually makes a difference when opening Xlsx
 270          //        files in Excel2003 with the compatibility pack. It's not documented behaviour,
 271          //        and makes for a real WTF!
 272  
 273          // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does
 274          // for conditional formatting). Otherwise it will apparently not be picked up in conditional
 275          // formatting style dialog
 276          if ($font->getBold() !== null) {
 277              $objWriter->startElement('b');
 278              $objWriter->writeAttribute('val', $font->getBold() ? '1' : '0');
 279              $objWriter->endElement();
 280          }
 281  
 282          // Italic
 283          if ($font->getItalic() !== null) {
 284              $objWriter->startElement('i');
 285              $objWriter->writeAttribute('val', $font->getItalic() ? '1' : '0');
 286              $objWriter->endElement();
 287          }
 288  
 289          // Strikethrough
 290          if ($font->getStrikethrough() !== null) {
 291              $objWriter->startElement('strike');
 292              $objWriter->writeAttribute('val', $font->getStrikethrough() ? '1' : '0');
 293              $objWriter->endElement();
 294          }
 295  
 296          // Underline
 297          if ($font->getUnderline() !== null) {
 298              $objWriter->startElement('u');
 299              $objWriter->writeAttribute('val', $font->getUnderline());
 300              $objWriter->endElement();
 301          }
 302  
 303          // Superscript / subscript
 304          if ($font->getSuperscript() === true || $font->getSubscript() === true) {
 305              $objWriter->startElement('vertAlign');
 306              if ($font->getSuperscript() === true) {
 307                  $objWriter->writeAttribute('val', 'superscript');
 308              } elseif ($font->getSubscript() === true) {
 309                  $objWriter->writeAttribute('val', 'subscript');
 310              }
 311              $objWriter->endElement();
 312          }
 313  
 314          // Size
 315          if ($font->getSize() !== null) {
 316              $objWriter->startElement('sz');
 317              $objWriter->writeAttribute('val', StringHelper::formatNumber($font->getSize()));
 318              $objWriter->endElement();
 319          }
 320  
 321          // Foreground color
 322          if ($font->getColor()->getARGB() !== null) {
 323              $objWriter->startElement('color');
 324              $objWriter->writeAttribute('rgb', $font->getColor()->getARGB());
 325              $objWriter->endElement();
 326          }
 327  
 328          // Name
 329          if ($font->getName() !== null) {
 330              $objWriter->startElement('name');
 331              $objWriter->writeAttribute('val', $font->getName());
 332              $objWriter->endElement();
 333          }
 334  
 335          $objWriter->endElement();
 336      }
 337  
 338      /**
 339       * Write Border.
 340       */
 341      private function writeBorder(XMLWriter $objWriter, Borders $borders): void
 342      {
 343          // Write border
 344          $objWriter->startElement('border');
 345          // Diagonal?
 346          switch ($borders->getDiagonalDirection()) {
 347              case Borders::DIAGONAL_UP:
 348                  $objWriter->writeAttribute('diagonalUp', 'true');
 349                  $objWriter->writeAttribute('diagonalDown', 'false');
 350  
 351                  break;
 352              case Borders::DIAGONAL_DOWN:
 353                  $objWriter->writeAttribute('diagonalUp', 'false');
 354                  $objWriter->writeAttribute('diagonalDown', 'true');
 355  
 356                  break;
 357              case Borders::DIAGONAL_BOTH:
 358                  $objWriter->writeAttribute('diagonalUp', 'true');
 359                  $objWriter->writeAttribute('diagonalDown', 'true');
 360  
 361                  break;
 362          }
 363  
 364          // BorderPr
 365          $this->writeBorderPr($objWriter, 'left', $borders->getLeft());
 366          $this->writeBorderPr($objWriter, 'right', $borders->getRight());
 367          $this->writeBorderPr($objWriter, 'top', $borders->getTop());
 368          $this->writeBorderPr($objWriter, 'bottom', $borders->getBottom());
 369          $this->writeBorderPr($objWriter, 'diagonal', $borders->getDiagonal());
 370          $objWriter->endElement();
 371      }
 372  
 373      /**
 374       * Write Cell Style Xf.
 375       */
 376      private function writeCellStyleXf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style, Spreadsheet $spreadsheet): void
 377      {
 378          // xf
 379          $objWriter->startElement('xf');
 380          $objWriter->writeAttribute('xfId', '0');
 381          $objWriter->writeAttribute('fontId', (string) (int) $this->getParentWriter()->getFontHashTable()->getIndexForHashCode($style->getFont()->getHashCode()));
 382          if ($style->getQuotePrefix()) {
 383              $objWriter->writeAttribute('quotePrefix', '1');
 384          }
 385  
 386          if ($style->getNumberFormat()->getBuiltInFormatCode() === false) {
 387              $objWriter->writeAttribute('numFmtId', (string) (int) ($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($style->getNumberFormat()->getHashCode()) + 164));
 388          } else {
 389              $objWriter->writeAttribute('numFmtId', (string) (int) $style->getNumberFormat()->getBuiltInFormatCode());
 390          }
 391  
 392          $objWriter->writeAttribute('fillId', (string) (int) $this->getParentWriter()->getFillHashTable()->getIndexForHashCode($style->getFill()->getHashCode()));
 393          $objWriter->writeAttribute('borderId', (string) (int) $this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($style->getBorders()->getHashCode()));
 394  
 395          // Apply styles?
 396          $objWriter->writeAttribute('applyFont', ($spreadsheet->getDefaultStyle()->getFont()->getHashCode() != $style->getFont()->getHashCode()) ? '1' : '0');
 397          $objWriter->writeAttribute('applyNumberFormat', ($spreadsheet->getDefaultStyle()->getNumberFormat()->getHashCode() != $style->getNumberFormat()->getHashCode()) ? '1' : '0');
 398          $objWriter->writeAttribute('applyFill', ($spreadsheet->getDefaultStyle()->getFill()->getHashCode() != $style->getFill()->getHashCode()) ? '1' : '0');
 399          $objWriter->writeAttribute('applyBorder', ($spreadsheet->getDefaultStyle()->getBorders()->getHashCode() != $style->getBorders()->getHashCode()) ? '1' : '0');
 400          $objWriter->writeAttribute('applyAlignment', ($spreadsheet->getDefaultStyle()->getAlignment()->getHashCode() != $style->getAlignment()->getHashCode()) ? '1' : '0');
 401          if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
 402              $objWriter->writeAttribute('applyProtection', 'true');
 403          }
 404  
 405          // alignment
 406          $objWriter->startElement('alignment');
 407          $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? '';
 408          $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? '';
 409          if ($horizontal !== '') {
 410              $objWriter->writeAttribute('horizontal', $horizontal);
 411          }
 412          if ($vertical !== '') {
 413              $objWriter->writeAttribute('vertical', $vertical);
 414          }
 415  
 416          $textRotation = 0;
 417          if ($style->getAlignment()->getTextRotation() >= 0) {
 418              $textRotation = $style->getAlignment()->getTextRotation();
 419          } else {
 420              $textRotation = 90 - $style->getAlignment()->getTextRotation();
 421          }
 422          $objWriter->writeAttribute('textRotation', (string) $textRotation);
 423  
 424          $objWriter->writeAttribute('wrapText', ($style->getAlignment()->getWrapText() ? 'true' : 'false'));
 425          $objWriter->writeAttribute('shrinkToFit', ($style->getAlignment()->getShrinkToFit() ? 'true' : 'false'));
 426  
 427          if ($style->getAlignment()->getIndent() > 0) {
 428              $objWriter->writeAttribute('indent', (string) $style->getAlignment()->getIndent());
 429          }
 430          if ($style->getAlignment()->getReadOrder() > 0) {
 431              $objWriter->writeAttribute('readingOrder', (string) $style->getAlignment()->getReadOrder());
 432          }
 433          $objWriter->endElement();
 434  
 435          // protection
 436          if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
 437              $objWriter->startElement('protection');
 438              if ($style->getProtection()->getLocked() != Protection::PROTECTION_INHERIT) {
 439                  $objWriter->writeAttribute('locked', ($style->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
 440              }
 441              if ($style->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
 442                  $objWriter->writeAttribute('hidden', ($style->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
 443              }
 444              $objWriter->endElement();
 445          }
 446  
 447          $objWriter->endElement();
 448      }
 449  
 450      /**
 451       * Write Cell Style Dxf.
 452       */
 453      private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $style): void
 454      {
 455          // dxf
 456          $objWriter->startElement('dxf');
 457  
 458          // font
 459          $this->writeFont($objWriter, $style->getFont());
 460  
 461          // numFmt
 462          $this->writeNumFmt($objWriter, $style->getNumberFormat());
 463  
 464          // fill
 465          $this->writeFill($objWriter, $style->getFill());
 466  
 467          // alignment
 468          $objWriter->startElement('alignment');
 469          $horizontal = Alignment::HORIZONTAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getHorizontal()] ?? '';
 470          if ($horizontal) {
 471              $objWriter->writeAttribute('horizontal', $horizontal);
 472          }
 473          $vertical = Alignment::VERTICAL_ALIGNMENT_FOR_XLSX[$style->getAlignment()->getVertical()] ?? '';
 474          if ($vertical) {
 475              $objWriter->writeAttribute('vertical', $vertical);
 476          }
 477  
 478          if ($style->getAlignment()->getTextRotation() !== null) {
 479              $textRotation = 0;
 480              if ($style->getAlignment()->getTextRotation() >= 0) {
 481                  $textRotation = $style->getAlignment()->getTextRotation();
 482              } else {
 483                  $textRotation = 90 - $style->getAlignment()->getTextRotation();
 484              }
 485              $objWriter->writeAttribute('textRotation', (string) $textRotation);
 486          }
 487          $objWriter->endElement();
 488  
 489          // border
 490          $this->writeBorder($objWriter, $style->getBorders());
 491  
 492          // protection
 493          if ((!empty($style->getProtection()->getLocked())) || (!empty($style->getProtection()->getHidden()))) {
 494              if (
 495                  $style->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT ||
 496                  $style->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT
 497              ) {
 498                  $objWriter->startElement('protection');
 499                  if (
 500                      ($style->getProtection()->getLocked() !== null) &&
 501                      ($style->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT)
 502                  ) {
 503                      $objWriter->writeAttribute('locked', ($style->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
 504                  }
 505                  if (
 506                      ($style->getProtection()->getHidden() !== null) &&
 507                      ($style->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT)
 508                  ) {
 509                      $objWriter->writeAttribute('hidden', ($style->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
 510                  }
 511                  $objWriter->endElement();
 512              }
 513          }
 514  
 515          $objWriter->endElement();
 516      }
 517  
 518      /**
 519       * Write BorderPr.
 520       *
 521       * @param string $name Element name
 522       */
 523      private function writeBorderPr(XMLWriter $objWriter, $name, Border $border): void
 524      {
 525          // Write BorderPr
 526          if ($border->getBorderStyle() != Border::BORDER_NONE) {
 527              $objWriter->startElement($name);
 528              $objWriter->writeAttribute('style', $border->getBorderStyle());
 529  
 530              // color
 531              if ($border->getColor()->getARGB() !== null) {
 532                  $objWriter->startElement('color');
 533                  $objWriter->writeAttribute('rgb', $border->getColor()->getARGB());
 534                  $objWriter->endElement();
 535  
 536                  $objWriter->endElement();
 537              }
 538          }
 539      }
 540  
 541      /**
 542       * Write NumberFormat.
 543       *
 544       * @param int $id Number Format identifier
 545       */
 546      private function writeNumFmt(XMLWriter $objWriter, ?NumberFormat $numberFormat, $id = 0): void
 547      {
 548          // Translate formatcode
 549          $formatCode = ($numberFormat === null) ? null : $numberFormat->getFormatCode();
 550  
 551          // numFmt
 552          if ($formatCode !== null) {
 553              $objWriter->startElement('numFmt');
 554              $objWriter->writeAttribute('numFmtId', (string) ($id + 164));
 555              $objWriter->writeAttribute('formatCode', $formatCode);
 556              $objWriter->endElement();
 557          }
 558      }
 559  
 560      /**
 561       * Get an array of all styles.
 562       *
 563       * @return \PhpOffice\PhpSpreadsheet\Style\Style[] All styles in PhpSpreadsheet
 564       */
 565      public function allStyles(Spreadsheet $spreadsheet)
 566      {
 567          return $spreadsheet->getCellXfCollection();
 568      }
 569  
 570      /**
 571       * Get an array of all conditional styles.
 572       *
 573       * @return Conditional[] All conditional styles in PhpSpreadsheet
 574       */
 575      public function allConditionalStyles(Spreadsheet $spreadsheet)
 576      {
 577          // Get an array of all styles
 578          $aStyles = [];
 579  
 580          $sheetCount = $spreadsheet->getSheetCount();
 581          for ($i = 0; $i < $sheetCount; ++$i) {
 582              foreach ($spreadsheet->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) {
 583                  foreach ($conditionalStyles as $conditionalStyle) {
 584                      $aStyles[] = $conditionalStyle;
 585                  }
 586              }
 587          }
 588  
 589          return $aStyles;
 590      }
 591  
 592      /**
 593       * Get an array of all fills.
 594       *
 595       * @return Fill[] All fills in PhpSpreadsheet
 596       */
 597      public function allFills(Spreadsheet $spreadsheet)
 598      {
 599          // Get an array of unique fills
 600          $aFills = [];
 601  
 602          // Two first fills are predefined
 603          $fill0 = new Fill();
 604          $fill0->setFillType(Fill::FILL_NONE);
 605          $aFills[] = $fill0;
 606  
 607          $fill1 = new Fill();
 608          $fill1->setFillType(Fill::FILL_PATTERN_GRAY125);
 609          $aFills[] = $fill1;
 610          // The remaining fills
 611          $aStyles = $this->allStyles($spreadsheet);
 612          /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
 613          foreach ($aStyles as $style) {
 614              if (!isset($aFills[$style->getFill()->getHashCode()])) {
 615                  $aFills[$style->getFill()->getHashCode()] = $style->getFill();
 616              }
 617          }
 618  
 619          return $aFills;
 620      }
 621  
 622      /**
 623       * Get an array of all fonts.
 624       *
 625       * @return Font[] All fonts in PhpSpreadsheet
 626       */
 627      public function allFonts(Spreadsheet $spreadsheet)
 628      {
 629          // Get an array of unique fonts
 630          $aFonts = [];
 631          $aStyles = $this->allStyles($spreadsheet);
 632  
 633          /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
 634          foreach ($aStyles as $style) {
 635              if (!isset($aFonts[$style->getFont()->getHashCode()])) {
 636                  $aFonts[$style->getFont()->getHashCode()] = $style->getFont();
 637              }
 638          }
 639  
 640          return $aFonts;
 641      }
 642  
 643      /**
 644       * Get an array of all borders.
 645       *
 646       * @return Borders[] All borders in PhpSpreadsheet
 647       */
 648      public function allBorders(Spreadsheet $spreadsheet)
 649      {
 650          // Get an array of unique borders
 651          $aBorders = [];
 652          $aStyles = $this->allStyles($spreadsheet);
 653  
 654          /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
 655          foreach ($aStyles as $style) {
 656              if (!isset($aBorders[$style->getBorders()->getHashCode()])) {
 657                  $aBorders[$style->getBorders()->getHashCode()] = $style->getBorders();
 658              }
 659          }
 660  
 661          return $aBorders;
 662      }
 663  
 664      /**
 665       * Get an array of all number formats.
 666       *
 667       * @return NumberFormat[] All number formats in PhpSpreadsheet
 668       */
 669      public function allNumberFormats(Spreadsheet $spreadsheet)
 670      {
 671          // Get an array of unique number formats
 672          $aNumFmts = [];
 673          $aStyles = $this->allStyles($spreadsheet);
 674  
 675          /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
 676          foreach ($aStyles as $style) {
 677              if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !isset($aNumFmts[$style->getNumberFormat()->getHashCode()])) {
 678                  $aNumFmts[$style->getNumberFormat()->getHashCode()] = $style->getNumberFormat();
 679              }
 680          }
 681  
 682          return $aNumFmts;
 683      }
 684  }