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;
   4  
   5  use PhpOffice\PhpSpreadsheet\Shared\File;
   6  use PhpOffice\PhpSpreadsheet\Spreadsheet;
   7  use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
   8  use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
   9  use PhpOffice\PhpSpreadsheet\Writer\Ods\Meta;
  10  use PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf;
  11  use PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype;
  12  use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
  13  use PhpOffice\PhpSpreadsheet\Writer\Ods\Styles;
  14  use PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails;
  15  use ZipStream\Exception\OverflowException;
  16  use ZipStream\Option\Archive;
  17  use ZipStream\ZipStream;
  18  
  19  class Ods extends BaseWriter
  20  {
  21      /**
  22       * Private writer parts.
  23       *
  24       * @var Ods\WriterPart[]
  25       */
  26      private $writerParts = [];
  27  
  28      /**
  29       * Private PhpSpreadsheet.
  30       *
  31       * @var Spreadsheet
  32       */
  33      private $spreadSheet;
  34  
  35      /**
  36       * Create a new Ods.
  37       */
  38      public function __construct(Spreadsheet $spreadsheet)
  39      {
  40          $this->setSpreadsheet($spreadsheet);
  41  
  42          $writerPartsArray = [
  43              'content' => Content::class,
  44              'meta' => Meta::class,
  45              'meta_inf' => MetaInf::class,
  46              'mimetype' => Mimetype::class,
  47              'settings' => Settings::class,
  48              'styles' => Styles::class,
  49              'thumbnails' => Thumbnails::class,
  50          ];
  51  
  52          foreach ($writerPartsArray as $writer => $class) {
  53              $this->writerParts[$writer] = new $class($this);
  54          }
  55      }
  56  
  57      /**
  58       * Get writer part.
  59       *
  60       * @param string $pPartName Writer part name
  61       *
  62       * @return null|Ods\WriterPart
  63       */
  64      public function getWriterPart($pPartName)
  65      {
  66          if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
  67              return $this->writerParts[strtolower($pPartName)];
  68          }
  69  
  70          return null;
  71      }
  72  
  73      /**
  74       * Save PhpSpreadsheet to file.
  75       *
  76       * @param resource|string $pFilename
  77       */
  78      public function save($pFilename): void
  79      {
  80          if (!$this->spreadSheet) {
  81              throw new WriterException('PhpSpreadsheet object unassigned.');
  82          }
  83  
  84          // garbage collect
  85          $this->spreadSheet->garbageCollect();
  86  
  87          $this->openFileHandle($pFilename);
  88  
  89          $zip = $this->createZip();
  90  
  91          $zip->addFile('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
  92          $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
  93          $zip->addFile('content.xml', $this->getWriterPart('content')->write());
  94          $zip->addFile('meta.xml', $this->getWriterPart('meta')->write());
  95          $zip->addFile('mimetype', $this->getWriterPart('mimetype')->write());
  96          $zip->addFile('settings.xml', $this->getWriterPart('settings')->write());
  97          $zip->addFile('styles.xml', $this->getWriterPart('styles')->write());
  98  
  99          // Close file
 100          try {
 101              $zip->finish();
 102          } catch (OverflowException $e) {
 103              throw new WriterException('Could not close resource.');
 104          }
 105  
 106          $this->maybeCloseFileHandle();
 107      }
 108  
 109      /**
 110       * Create zip object.
 111       *
 112       * @return ZipStream
 113       */
 114      private function createZip()
 115      {
 116          // Try opening the ZIP file
 117          if (!is_resource($this->fileHandle)) {
 118              throw new WriterException('Could not open resource for writing.');
 119          }
 120  
 121          // Create new ZIP stream
 122          $options = new Archive();
 123          $options->setEnableZip64(false);
 124          $options->setOutputStream($this->fileHandle);
 125  
 126          return new ZipStream(null, $options);
 127      }
 128  
 129      /**
 130       * Get Spreadsheet object.
 131       *
 132       * @return Spreadsheet
 133       */
 134      public function getSpreadsheet()
 135      {
 136          if ($this->spreadSheet !== null) {
 137              return $this->spreadSheet;
 138          }
 139  
 140          throw new WriterException('No PhpSpreadsheet assigned.');
 141      }
 142  
 143      /**
 144       * Set Spreadsheet object.
 145       *
 146       * @param Spreadsheet $spreadsheet PhpSpreadsheet object
 147       *
 148       * @return $this
 149       */
 150      public function setSpreadsheet(Spreadsheet $spreadsheet)
 151      {
 152          $this->spreadSheet = $spreadsheet;
 153  
 154          return $this;
 155      }
 156  }