Sample.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheet\Helper;
  3. use PhpOffice\PhpSpreadsheet\IOFactory;
  4. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  5. use PhpOffice\PhpSpreadsheet\Writer\IWriter;
  6. use RecursiveDirectoryIterator;
  7. use RecursiveIteratorIterator;
  8. use RecursiveRegexIterator;
  9. use ReflectionClass;
  10. use RegexIterator;
  11. use RuntimeException;
  12. /**
  13. * Helper class to be used in sample code.
  14. */
  15. class Sample
  16. {
  17. /**
  18. * Returns whether we run on CLI or browser.
  19. *
  20. * @return bool
  21. */
  22. public function isCli()
  23. {
  24. return PHP_SAPI === 'cli';
  25. }
  26. /**
  27. * Return the filename currently being executed.
  28. *
  29. * @return string
  30. */
  31. public function getScriptFilename()
  32. {
  33. return basename($_SERVER['SCRIPT_FILENAME'], '.php');
  34. }
  35. /**
  36. * Whether we are executing the index page.
  37. *
  38. * @return bool
  39. */
  40. public function isIndex()
  41. {
  42. return $this->getScriptFilename() === 'index';
  43. }
  44. /**
  45. * Return the page title.
  46. *
  47. * @return string
  48. */
  49. public function getPageTitle()
  50. {
  51. return $this->isIndex() ? 'PHPSpreadsheet' : $this->getScriptFilename();
  52. }
  53. /**
  54. * Return the page heading.
  55. *
  56. * @return string
  57. */
  58. public function getPageHeading()
  59. {
  60. return $this->isIndex() ? '' : '<h1>' . str_replace('_', ' ', $this->getScriptFilename()) . '</h1>';
  61. }
  62. /**
  63. * Returns an array of all known samples.
  64. *
  65. * @return string[][] [$name => $path]
  66. */
  67. public function getSamples()
  68. {
  69. // Populate samples
  70. $baseDir = realpath(__DIR__ . '/../../../samples');
  71. $directory = new RecursiveDirectoryIterator($baseDir);
  72. $iterator = new RecursiveIteratorIterator($directory);
  73. $regex = new RegexIterator($iterator, '/^.+\.php$/', RecursiveRegexIterator::GET_MATCH);
  74. $files = [];
  75. foreach ($regex as $file) {
  76. $file = str_replace(str_replace('\\', '/', $baseDir) . '/', '', str_replace('\\', '/', $file[0]));
  77. $info = pathinfo($file);
  78. $category = str_replace('_', ' ', $info['dirname']);
  79. $name = str_replace('_', ' ', preg_replace('/(|\.php)/', '', $info['filename']));
  80. if (!in_array($category, ['.', 'boostrap', 'templates'])) {
  81. if (!isset($files[$category])) {
  82. $files[$category] = [];
  83. }
  84. $files[$category][$name] = $file;
  85. }
  86. }
  87. // Sort everything
  88. ksort($files);
  89. foreach ($files as &$f) {
  90. asort($f);
  91. }
  92. return $files;
  93. }
  94. /**
  95. * Write documents.
  96. *
  97. * @param string $filename
  98. * @param string[] $writers
  99. */
  100. public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls']): void
  101. {
  102. // Set active sheet index to the first sheet, so Excel opens this as the first sheet
  103. $spreadsheet->setActiveSheetIndex(0);
  104. // Write documents
  105. foreach ($writers as $writerType) {
  106. $path = $this->getFilename($filename, mb_strtolower($writerType));
  107. $writer = IOFactory::createWriter($spreadsheet, $writerType);
  108. $callStartTime = microtime(true);
  109. $writer->save($path);
  110. $this->logWrite($writer, $path, $callStartTime);
  111. }
  112. $this->logEndingNotes();
  113. }
  114. protected function isDirOrMkdir(string $folder): bool
  115. {
  116. return \is_dir($folder) || \mkdir($folder);
  117. }
  118. /**
  119. * Returns the temporary directory and make sure it exists.
  120. *
  121. * @return string
  122. */
  123. private function getTemporaryFolder()
  124. {
  125. $tempFolder = sys_get_temp_dir() . '/phpspreadsheet';
  126. if (!$this->isDirOrMkdir($tempFolder)) {
  127. throw new RuntimeException(sprintf('Directory "%s" was not created', $tempFolder));
  128. }
  129. return $tempFolder;
  130. }
  131. /**
  132. * Returns the filename that should be used for sample output.
  133. *
  134. * @param string $filename
  135. * @param string $extension
  136. *
  137. * @return string
  138. */
  139. public function getFilename($filename, $extension = 'xlsx')
  140. {
  141. $originalExtension = pathinfo($filename, PATHINFO_EXTENSION);
  142. return $this->getTemporaryFolder() . '/' . str_replace('.' . $originalExtension, '.' . $extension, basename($filename));
  143. }
  144. /**
  145. * Return a random temporary file name.
  146. *
  147. * @param string $extension
  148. *
  149. * @return string
  150. */
  151. public function getTemporaryFilename($extension = 'xlsx')
  152. {
  153. $temporaryFilename = tempnam($this->getTemporaryFolder(), 'phpspreadsheet-');
  154. unlink($temporaryFilename);
  155. return $temporaryFilename . '.' . $extension;
  156. }
  157. public function log($message): void
  158. {
  159. $eol = $this->isCli() ? PHP_EOL : '<br />';
  160. echo date('H:i:s ') . $message . $eol;
  161. }
  162. /**
  163. * Log ending notes.
  164. */
  165. public function logEndingNotes(): void
  166. {
  167. // Do not show execution time for index
  168. $this->log('Peak memory usage: ' . (memory_get_peak_usage(true) / 1024 / 1024) . 'MB');
  169. }
  170. /**
  171. * Log a line about the write operation.
  172. *
  173. * @param string $path
  174. * @param float $callStartTime
  175. */
  176. public function logWrite(IWriter $writer, $path, $callStartTime): void
  177. {
  178. $callEndTime = microtime(true);
  179. $callTime = $callEndTime - $callStartTime;
  180. $reflection = new ReflectionClass($writer);
  181. $format = $reflection->getShortName();
  182. $message = "Write {$format} format to <code>{$path}</code> in " . sprintf('%.4f', $callTime) . ' seconds';
  183. $this->log($message);
  184. }
  185. /**
  186. * Log a line about the read operation.
  187. *
  188. * @param string $format
  189. * @param string $path
  190. * @param float $callStartTime
  191. */
  192. public function logRead($format, $path, $callStartTime): void
  193. {
  194. $callEndTime = microtime(true);
  195. $callTime = $callEndTime - $callStartTime;
  196. $message = "Read {$format} format from <code>{$path}</code> in " . sprintf('%.4f', $callTime) . ' seconds';
  197. $this->log($message);
  198. }
  199. }