Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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