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;
   4  
   5  use PhpOffice\PhpSpreadsheet\Spreadsheet;
   6  use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
   7  use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
   8  use PhpOffice\PhpSpreadsheet\Writer\Ods\Meta;
   9  use PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf;
  10  use PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype;
  11  use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
  12  use PhpOffice\PhpSpreadsheet\Writer\Ods\Styles;
  13  use PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails;
  14  use ZipStream\Exception\OverflowException;
  15  use ZipStream\Option\Archive;
  16  use ZipStream\ZipStream;
  17  
  18  class Ods extends BaseWriter
  19  {
  20      /**
  21       * Private PhpSpreadsheet.
  22       *
  23       * @var Spreadsheet
  24       */
  25      private $spreadSheet;
  26  
  27      /**
  28       * @var Content
  29       */
  30      private $writerPartContent;
  31  
  32      /**
  33       * @var Meta
  34       */
  35      private $writerPartMeta;
  36  
  37      /**
  38       * @var MetaInf
  39       */
  40      private $writerPartMetaInf;
  41  
  42      /**
  43       * @var Mimetype
  44       */
  45      private $writerPartMimetype;
  46  
  47      /**
  48       * @var Settings
  49       */
  50      private $writerPartSettings;
  51  
  52      /**
  53       * @var Styles
  54       */
  55      private $writerPartStyles;
  56  
  57      /**
  58       * @var Thumbnails
  59       */
  60      private $writerPartThumbnails;
  61  
  62      /**
  63       * Create a new Ods.
  64       */
  65      public function __construct(Spreadsheet $spreadsheet)
  66      {
  67          $this->setSpreadsheet($spreadsheet);
  68  
  69          $this->writerPartContent = new Content($this);
  70          $this->writerPartMeta = new Meta($this);
  71          $this->writerPartMetaInf = new MetaInf($this);
  72          $this->writerPartMimetype = new Mimetype($this);
  73          $this->writerPartSettings = new Settings($this);
  74          $this->writerPartStyles = new Styles($this);
  75          $this->writerPartThumbnails = new Thumbnails($this);
  76      }
  77  
  78      public function getWriterPartContent(): Content
  79      {
  80          return $this->writerPartContent;
  81      }
  82  
  83      public function getWriterPartMeta(): Meta
  84      {
  85          return $this->writerPartMeta;
  86      }
  87  
  88      public function getWriterPartMetaInf(): MetaInf
  89      {
  90          return $this->writerPartMetaInf;
  91      }
  92  
  93      public function getWriterPartMimetype(): Mimetype
  94      {
  95          return $this->writerPartMimetype;
  96      }
  97  
  98      public function getWriterPartSettings(): Settings
  99      {
 100          return $this->writerPartSettings;
 101      }
 102  
 103      public function getWriterPartStyles(): Styles
 104      {
 105          return $this->writerPartStyles;
 106      }
 107  
 108      public function getWriterPartThumbnails(): Thumbnails
 109      {
 110          return $this->writerPartThumbnails;
 111      }
 112  
 113      /**
 114       * Save PhpSpreadsheet to file.
 115       *
 116       * @param resource|string $filename
 117       */
 118      public function save($filename, int $flags = 0): void
 119      {
 120          if (!$this->spreadSheet) {
 121              throw new WriterException('PhpSpreadsheet object unassigned.');
 122          }
 123  
 124          $this->processFlags($flags);
 125  
 126          // garbage collect
 127          $this->spreadSheet->garbageCollect();
 128  
 129          $this->openFileHandle($filename);
 130  
 131          $zip = $this->createZip();
 132  
 133          $zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
 134          $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
 135          // Settings always need to be written before Content; Styles after Content
 136          $zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
 137          $zip->addFile('content.xml', $this->getWriterPartcontent()->write());
 138          $zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
 139          $zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
 140          $zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
 141  
 142          // Close file
 143          try {
 144              $zip->finish();
 145          } catch (OverflowException $e) {
 146              throw new WriterException('Could not close resource.');
 147          }
 148  
 149          $this->maybeCloseFileHandle();
 150      }
 151  
 152      /**
 153       * Create zip object.
 154       *
 155       * @return ZipStream
 156       */
 157      private function createZip()
 158      {
 159          // Try opening the ZIP file
 160          if (!is_resource($this->fileHandle)) {
 161              throw new WriterException('Could not open resource for writing.');
 162          }
 163  
 164          // Create new ZIP stream
 165          $options = new Archive();
 166          $options->setEnableZip64(false);
 167          $options->setOutputStream($this->fileHandle);
 168  
 169          return new ZipStream(null, $options);
 170      }
 171  
 172      /**
 173       * Get Spreadsheet object.
 174       *
 175       * @return Spreadsheet
 176       */
 177      public function getSpreadsheet()
 178      {
 179          if ($this->spreadSheet !== null) {
 180              return $this->spreadSheet;
 181          }
 182  
 183          throw new WriterException('No PhpSpreadsheet assigned.');
 184      }
 185  
 186      /**
 187       * Set Spreadsheet object.
 188       *
 189       * @param Spreadsheet $spreadsheet PhpSpreadsheet object
 190       *
 191       * @return $this
 192       */
 193      public function setSpreadsheet(Spreadsheet $spreadsheet)
 194      {
 195          $this->spreadSheet = $spreadsheet;
 196  
 197          return $this;
 198      }
 199  }