Differences Between: [Versions 402 and 403]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace OpenSpout\Writer; 6 7 use OpenSpout\Common\Entity\Row; 8 use OpenSpout\Common\Exception\IOException; 9 use OpenSpout\Writer\Exception\WriterNotOpenedException; 10 11 abstract class AbstractWriter implements WriterInterface 12 { 13 /** @var resource Pointer to the file/stream we will write to */ 14 protected $filePointer; 15 16 /** @var string document creator */ 17 protected string $creator = 'OpenSpout'; 18 19 /** @var string Content-Type value for the header - to be defined by child class */ 20 protected static string $headerContentType; 21 22 /** @var string Path to the output file */ 23 private string $outputFilePath; 24 25 /** @var bool Indicates whether the writer has been opened or not */ 26 private bool $isWriterOpened = false; 27 28 /** @var 0|positive-int */ 29 private int $writtenRowCount = 0; 30 31 final public function openToFile($outputFilePath): void 32 { 33 $this->outputFilePath = $outputFilePath; 34 35 $errorMessage = null; 36 set_error_handler(static function ($nr, $message) use (&$errorMessage): bool { 37 $errorMessage = $message; 38 39 return true; 40 }); 41 42 $resource = fopen($this->outputFilePath, 'w'); 43 restore_error_handler(); 44 if (null !== $errorMessage) { 45 throw new IOException("Unable to open file {$this->outputFilePath}: {$errorMessage}"); 46 } 47 \assert(false !== $resource); 48 $this->filePointer = $resource; 49 50 $this->openWriter(); 51 $this->isWriterOpened = true; 52 } 53 54 /** 55 * @codeCoverageIgnore 56 * 57 * @param mixed $outputFileName 58 */ 59 final public function openToBrowser($outputFileName): void 60 { 61 $this->outputFilePath = basename($outputFileName); 62 63 $resource = fopen('php://output', 'w'); 64 \assert(false !== $resource); 65 $this->filePointer = $resource; 66 67 // Clear any previous output (otherwise the generated file will be corrupted) 68 // @see https://github.com/box/spout/issues/241 69 if (ob_get_length() > 0) { 70 ob_end_clean(); 71 } 72 73 /* 74 * Set headers 75 * 76 * For newer browsers such as Firefox, Chrome, Opera, Safari, etc., they all support and use `filename*` 77 * specified by the new standard, even if they do not automatically decode filename; it does not matter; 78 * and for older versions of Internet Explorer, they are not recognized `filename*`, will automatically 79 * ignore it and use the old `filename` (the only minor flaw is that there must be an English suffix name). 80 * In this way, the multi-browser multi-language compatibility problem is perfectly solved, which does not 81 * require UA judgment and is more in line with the standard. 82 * 83 * @see https://github.com/box/spout/issues/745 84 * @see https://tools.ietf.org/html/rfc6266 85 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition 86 */ 87 header('Content-Type: '.static::$headerContentType); 88 header( 89 'Content-Disposition: attachment; '. 90 'filename="'.rawurlencode($this->outputFilePath).'"; '. 91 'filename*=UTF-8\'\''.rawurlencode($this->outputFilePath) 92 ); 93 94 /* 95 * When forcing the download of a file over SSL,IE8 and lower browsers fail 96 * if the Cache-Control and Pragma headers are not set. 97 * 98 * @see http://support.microsoft.com/KB/323308 99 * @see https://github.com/liuggio/ExcelBundle/issues/45 100 */ 101 header('Cache-Control: max-age=0'); 102 header('Pragma: public'); 103 104 $this->openWriter(); 105 $this->isWriterOpened = true; 106 } 107 108 final public function addRow(Row $row): void 109 { 110 if (!$this->isWriterOpened) { 111 throw new WriterNotOpenedException('The writer needs to be opened before adding row.'); 112 } 113 114 $this->addRowToWriter($row); 115 ++$this->writtenRowCount; 116 } 117 118 final public function addRows(array $rows): void 119 { 120 foreach ($rows as $row) { 121 $this->addRow($row); 122 } 123 } 124 125 final public function setCreator(string $creator): void 126 { 127 $this->creator = $creator; 128 } 129 130 final public function getWrittenRowCount(): int 131 { 132 return $this->writtenRowCount; 133 } 134 135 final public function close(): void 136 { 137 if (!$this->isWriterOpened) { 138 return; 139 } 140 141 $this->closeWriter(); 142 143 fclose($this->filePointer); 144 145 $this->isWriterOpened = false; 146 } 147 148 /** 149 * Opens the streamer and makes it ready to accept data. 150 * 151 * @throws IOException If the writer cannot be opened 152 */ 153 abstract protected function openWriter(): void; 154 155 /** 156 * Adds a row to the currently opened writer. 157 * 158 * @param Row $row The row containing cells and styles 159 * 160 * @throws WriterNotOpenedException If the workbook is not created yet 161 * @throws IOException If unable to write data 162 */ 163 abstract protected function addRowToWriter(Row $row): void; 164 165 /** 166 * Closes the streamer, preventing any additional writing. 167 */ 168 abstract protected function closeWriter(): void; 169 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body