Ods.php 5.0 KB

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