Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Writer; 4 5 use PhpOffice\PhpSpreadsheet\Calculation\Calculation; 6 use PhpOffice\PhpSpreadsheet\Spreadsheet; 7 8 class Csv extends BaseWriter 9 { 10 /** 11 * PhpSpreadsheet object. 12 * 13 * @var Spreadsheet 14 */ 15 private $spreadsheet; 16 17 /** 18 * Delimiter. 19 * 20 * @var string 21 */ 22 private $delimiter = ','; 23 24 /** 25 * Enclosure. 26 * 27 * @var string 28 */ 29 private $enclosure = '"'; 30 31 /** 32 * Line ending. 33 * 34 * @var string 35 */ 36 private $lineEnding = PHP_EOL; 37 38 /** 39 * Sheet index to write. 40 * 41 * @var int 42 */ 43 private $sheetIndex = 0; 44 45 /** 46 * Whether to write a BOM (for UTF8). 47 * 48 * @var bool 49 */ 50 private $useBOM = false; 51 52 /** 53 * Whether to write a Separator line as the first line of the file 54 * sep=x. 55 * 56 * @var bool 57 */ 58 private $includeSeparatorLine = false; 59 60 /** 61 * Whether to write a fully Excel compatible CSV file. 62 * 63 * @var bool 64 */ 65 private $excelCompatibility = false; 66 67 /** 68 * Create a new CSV. 69 * 70 * @param Spreadsheet $spreadsheet Spreadsheet object 71 */ 72 public function __construct(Spreadsheet $spreadsheet) 73 { 74 $this->spreadsheet = $spreadsheet; 75 } 76 77 /** 78 * Save PhpSpreadsheet to file. 79 * 80 * @param resource|string $pFilename 81 */ 82 public function save($pFilename): void 83 { 84 // Fetch sheet 85 $sheet = $this->spreadsheet->getSheet($this->sheetIndex); 86 87 $saveDebugLog = Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog(); 88 Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false); 89 $saveArrayReturnType = Calculation::getArrayReturnType(); 90 Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_VALUE); 91 92 // Open file 93 $this->openFileHandle($pFilename); 94 95 if ($this->excelCompatibility) { 96 $this->setUseBOM(true); // Enforce UTF-8 BOM Header 97 $this->setIncludeSeparatorLine(true); // Set separator line 98 $this->setEnclosure('"'); // Set enclosure to " 99 $this->setDelimiter(';'); // Set delimiter to a semi-colon 100 $this->setLineEnding("\r\n"); 101 } 102 103 if ($this->useBOM) { 104 // Write the UTF-8 BOM code if required 105 fwrite($this->fileHandle, "\xEF\xBB\xBF"); 106 } 107 108 if ($this->includeSeparatorLine) { 109 // Write the separator line if required 110 fwrite($this->fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding); 111 } 112 113 // Identify the range that we need to extract from the worksheet 114 $maxCol = $sheet->getHighestDataColumn(); 115 $maxRow = $sheet->getHighestDataRow(); 116 117 // Write rows to file 118 for ($row = 1; $row <= $maxRow; ++$row) { 119 // Convert the row to an array... 120 $cellsArray = $sheet->rangeToArray('A' . $row . ':' . $maxCol . $row, '', $this->preCalculateFormulas); 121 // ... and write to the file 122 $this->writeLine($this->fileHandle, $cellsArray[0]); 123 } 124 125 $this->maybeCloseFileHandle(); 126 Calculation::setArrayReturnType($saveArrayReturnType); 127 Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); 128 } 129 130 /** 131 * Get delimiter. 132 * 133 * @return string 134 */ 135 public function getDelimiter() 136 { 137 return $this->delimiter; 138 } 139 140 /** 141 * Set delimiter. 142 * 143 * @param string $pValue Delimiter, defaults to ',' 144 * 145 * @return $this 146 */ 147 public function setDelimiter($pValue) 148 { 149 $this->delimiter = $pValue; 150 151 return $this; 152 } 153 154 /** 155 * Get enclosure. 156 * 157 * @return string 158 */ 159 public function getEnclosure() 160 { 161 return $this->enclosure; 162 } 163 164 /** 165 * Set enclosure. 166 * 167 * @param string $pValue Enclosure, defaults to " 168 * 169 * @return $this 170 */ 171 public function setEnclosure($pValue = '"') 172 { 173 $this->enclosure = $pValue; 174 175 return $this; 176 } 177 178 /** 179 * Get line ending. 180 * 181 * @return string 182 */ 183 public function getLineEnding() 184 { 185 return $this->lineEnding; 186 } 187 188 /** 189 * Set line ending. 190 * 191 * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) 192 * 193 * @return $this 194 */ 195 public function setLineEnding($pValue) 196 { 197 $this->lineEnding = $pValue; 198 199 return $this; 200 } 201 202 /** 203 * Get whether BOM should be used. 204 * 205 * @return bool 206 */ 207 public function getUseBOM() 208 { 209 return $this->useBOM; 210 } 211 212 /** 213 * Set whether BOM should be used. 214 * 215 * @param bool $pValue Use UTF-8 byte-order mark? Defaults to false 216 * 217 * @return $this 218 */ 219 public function setUseBOM($pValue) 220 { 221 $this->useBOM = $pValue; 222 223 return $this; 224 } 225 226 /** 227 * Get whether a separator line should be included. 228 * 229 * @return bool 230 */ 231 public function getIncludeSeparatorLine() 232 { 233 return $this->includeSeparatorLine; 234 } 235 236 /** 237 * Set whether a separator line should be included as the first line of the file. 238 * 239 * @param bool $pValue Use separator line? Defaults to false 240 * 241 * @return $this 242 */ 243 public function setIncludeSeparatorLine($pValue) 244 { 245 $this->includeSeparatorLine = $pValue; 246 247 return $this; 248 } 249 250 /** 251 * Get whether the file should be saved with full Excel Compatibility. 252 * 253 * @return bool 254 */ 255 public function getExcelCompatibility() 256 { 257 return $this->excelCompatibility; 258 } 259 260 /** 261 * Set whether the file should be saved with full Excel Compatibility. 262 * 263 * @param bool $pValue Set the file to be written as a fully Excel compatible csv file 264 * Note that this overrides other settings such as useBOM, enclosure and delimiter 265 * 266 * @return $this 267 */ 268 public function setExcelCompatibility($pValue) 269 { 270 $this->excelCompatibility = $pValue; 271 272 return $this; 273 } 274 275 /** 276 * Get sheet index. 277 * 278 * @return int 279 */ 280 public function getSheetIndex() 281 { 282 return $this->sheetIndex; 283 } 284 285 /** 286 * Set sheet index. 287 * 288 * @param int $pValue Sheet index 289 * 290 * @return $this 291 */ 292 public function setSheetIndex($pValue) 293 { 294 $this->sheetIndex = $pValue; 295 296 return $this; 297 } 298 299 private $enclosureRequired = true; 300 301 public function setEnclosureRequired(bool $value): self 302 { 303 $this->enclosureRequired = $value; 304 305 return $this; 306 } 307 308 public function getEnclosureRequired(): bool 309 { 310 return $this->enclosureRequired; 311 } 312 313 /** 314 * Write line to CSV file. 315 * 316 * @param resource $pFileHandle PHP filehandle 317 * @param array $pValues Array containing values in a row 318 */ 319 private function writeLine($pFileHandle, array $pValues): void 320 { 321 // No leading delimiter 322 $delimiter = ''; 323 324 // Build the line 325 $line = ''; 326 327 foreach ($pValues as $element) { 328 // Add delimiter 329 $line .= $delimiter; 330 $delimiter = $this->delimiter; 331 // Escape enclosures 332 $enclosure = $this->enclosure; 333 if ($enclosure) { 334 // If enclosure is not required, use enclosure only if 335 // element contains newline, delimiter, or enclosure. 336 if (!$this->enclosureRequired && strpbrk($element, "$delimiter$enclosure\n") === false) { 337 $enclosure = ''; 338 } else { 339 $element = str_replace($enclosure, $enclosure . $enclosure, $element); 340 } 341 } 342 // Add enclosed string 343 $line .= $enclosure . $element . $enclosure; 344 } 345 346 // Add line ending 347 $line .= $this->lineEnding; 348 349 // Write to file 350 fwrite($pFileHandle, $line); 351 } 352 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body