Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

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