Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  
   3  declare(strict_types=1);
   4  
   5  namespace OpenSpout\Writer\Common\Entity;
   6  
   7  use OpenSpout\Writer\AutoFilter;
   8  use OpenSpout\Writer\Common\ColumnWidth;
   9  use OpenSpout\Writer\Common\Manager\SheetManager;
  10  use OpenSpout\Writer\XLSX\Entity\SheetView;
  11  
  12  /**
  13   * External representation of a worksheet.
  14   */
  15  final class Sheet
  16  {
  17      public const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
  18  
  19      /** @var 0|positive-int Index of the sheet, based on order in the workbook (zero-based) */
  20      private int $index;
  21  
  22      /** @var string ID of the sheet's associated workbook. Used to restrict sheet name uniqueness enforcement to a single workbook */
  23      private string $associatedWorkbookId;
  24  
  25      /** @var string Name of the sheet */
  26      private string $name;
  27  
  28      /** @var bool Visibility of the sheet */
  29      private bool $isVisible;
  30  
  31      /** @var SheetManager Sheet manager */
  32      private SheetManager $sheetManager;
  33  
  34      private ?SheetView $sheetView = null;
  35  
  36      /** @var 0|positive-int */
  37      private int $writtenRowCount = 0;
  38  
  39      private ?AutoFilter $autoFilter = null;
  40  
  41      /** @var ColumnWidth[] Array of min-max-width arrays */
  42      private array $COLUMN_WIDTHS = [];
  43  
  44      /**
  45       * @param 0|positive-int $sheetIndex           Index of the sheet, based on order in the workbook (zero-based)
  46       * @param string         $associatedWorkbookId ID of the sheet's associated workbook
  47       * @param SheetManager   $sheetManager         To manage sheets
  48       */
  49      public function __construct(int $sheetIndex, string $associatedWorkbookId, SheetManager $sheetManager)
  50      {
  51          $this->index = $sheetIndex;
  52          $this->associatedWorkbookId = $associatedWorkbookId;
  53  
  54          $this->sheetManager = $sheetManager;
  55          $this->sheetManager->markWorkbookIdAsUsed($associatedWorkbookId);
  56  
  57          $this->setName(self::DEFAULT_SHEET_NAME_PREFIX.($sheetIndex + 1));
  58          $this->setIsVisible(true);
  59      }
  60  
  61      /**
  62       * @return 0|positive-int Index of the sheet, based on order in the workbook (zero-based)
  63       */
  64      public function getIndex(): int
  65      {
  66          return $this->index;
  67      }
  68  
  69      public function getAssociatedWorkbookId(): string
  70      {
  71          return $this->associatedWorkbookId;
  72      }
  73  
  74      /**
  75       * @return string Name of the sheet
  76       */
  77      public function getName(): string
  78      {
  79          return $this->name;
  80      }
  81  
  82      /**
  83       * Sets the name of the sheet. Note that Excel has some restrictions on the name:
  84       *  - it should not be blank
  85       *  - it should not exceed 31 characters
  86       *  - it should not contain these characters: \ / ? * : [ or ]
  87       *  - it should be unique.
  88       *
  89       * @param string $name Name of the sheet
  90       *
  91       * @throws \OpenSpout\Writer\Exception\InvalidSheetNameException if the sheet's name is invalid
  92       */
  93      public function setName(string $name): self
  94      {
  95          $this->sheetManager->throwIfNameIsInvalid($name, $this);
  96  
  97          $this->name = $name;
  98  
  99          $this->sheetManager->markSheetNameAsUsed($this);
 100  
 101          return $this;
 102      }
 103  
 104      /**
 105       * @return bool isVisible Visibility of the sheet
 106       */
 107      public function isVisible(): bool
 108      {
 109          return $this->isVisible;
 110      }
 111  
 112      /**
 113       * @param bool $isVisible Visibility of the sheet
 114       */
 115      public function setIsVisible(bool $isVisible): self
 116      {
 117          $this->isVisible = $isVisible;
 118  
 119          return $this;
 120      }
 121  
 122      /**
 123       * @return $this
 124       */
 125      public function setSheetView(SheetView $sheetView): self
 126      {
 127          $this->sheetView = $sheetView;
 128  
 129          return $this;
 130      }
 131  
 132      public function getSheetView(): ?SheetView
 133      {
 134          return $this->sheetView;
 135      }
 136  
 137      /**
 138       * @internal
 139       */
 140      public function incrementWrittenRowCount(): void
 141      {
 142          ++$this->writtenRowCount;
 143      }
 144  
 145      /**
 146       * @return 0|positive-int
 147       */
 148      public function getWrittenRowCount(): int
 149      {
 150          return $this->writtenRowCount;
 151      }
 152  
 153      /**
 154       * @return $this
 155       */
 156      public function setAutoFilter(?AutoFilter $autoFilter): self
 157      {
 158          $this->autoFilter = $autoFilter;
 159  
 160          return $this;
 161      }
 162  
 163      public function getAutoFilter(): ?AutoFilter
 164      {
 165          return $this->autoFilter;
 166      }
 167  
 168      /**
 169       * @param positive-int ...$columns One or more columns with this width
 170       */
 171      public function setColumnWidth(float $width, int ...$columns): void
 172      {
 173          // Gather sequences
 174          $sequence = [];
 175          foreach ($columns as $column) {
 176              $sequenceLength = \count($sequence);
 177              if ($sequenceLength > 0) {
 178                  $previousValue = $sequence[$sequenceLength - 1];
 179                  if ($column !== $previousValue + 1) {
 180                      $this->setColumnWidthForRange($width, $sequence[0], $previousValue);
 181                      $sequence = [];
 182                  }
 183              }
 184              $sequence[] = $column;
 185          }
 186          $this->setColumnWidthForRange($width, $sequence[0], $sequence[\count($sequence) - 1]);
 187      }
 188  
 189      /**
 190       * @param float        $width The width to set
 191       * @param positive-int $start First column index of the range
 192       * @param positive-int $end   Last column index of the range
 193       */
 194      public function setColumnWidthForRange(float $width, int $start, int $end): void
 195      {
 196          $this->COLUMN_WIDTHS[] = new ColumnWidth($start, $end, $width);
 197      }
 198  
 199      /**
 200       * @internal
 201       *
 202       * @return ColumnWidth[]
 203       */
 204      public function getColumnWidths(): array
 205      {
 206          return $this->COLUMN_WIDTHS;
 207      }
 208  }