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