Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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