diff --git a/docs/topics/reading-and-writing-to-file.md b/docs/topics/reading-and-writing-to-file.md index 19928f04..0bcc1909 100644 --- a/docs/topics/reading-and-writing-to-file.md +++ b/docs/topics/reading-and-writing-to-file.md @@ -449,8 +449,7 @@ $spreadsheet = $reader->loadSpreadsheetFromString($data); #### Setting CSV options Often, CSV files are not really "comma separated", or use semicolon (`;`) -as a separator. You can instruct -`\PhpOffice\PhpSpreadsheet\Reader\Csv` some options before reading a CSV +as a separator. You can set some options before reading a CSV file. The separator will be auto-detected, so in most cases it should not be necessary @@ -506,6 +505,12 @@ $reader->setSheetIndex(0); $spreadsheet = $reader->load('sample.csv'); ``` +The CSV reader will normally not load null strings into the spreadsheet. +To load them: +```php +$reader->setPreserveNullString(true); +``` + Finally, you can set a callback to be invoked when the constructor is executed, either through `new Csv()` or `IOFactory::load`, and have that callback set the customizable attributes to whatever @@ -584,8 +589,7 @@ $writer->save("05featuredemo.csv"); #### Setting CSV options Often, CSV files are not really "comma separated", or use semicolon (`;`) -as a separator. You can instruct -`\PhpOffice\PhpSpreadsheet\Writer\Csv` some options before writing a CSV +as a separator. You can set some options before writing a CSV file: ```php diff --git a/src/PhpSpreadsheet/Reader/Csv.php b/src/PhpSpreadsheet/Reader/Csv.php index b604ceef..65a71edb 100644 --- a/src/PhpSpreadsheet/Reader/Csv.php +++ b/src/PhpSpreadsheet/Reader/Csv.php @@ -103,6 +103,9 @@ class Csv extends BaseReader */ protected $preserveNumericFormatting = false; + /** @var bool */ + private $preserveNullString = false; + /** * Create a new CSV Reader instance. */ @@ -300,9 +303,11 @@ class Csv extends BaseReader } } - public function setTestAutoDetect(bool $value): void + public function setTestAutoDetect(bool $value): self { $this->testAutodetect = $value; + + return $this; } private function setAutoDetect(?string $value): ?string @@ -390,7 +395,7 @@ class Csv extends BaseReader foreach ($rowData as $rowDatum) { $this->convertBoolean($rowDatum, $preserveBooleanString); $numberFormatMask = $this->convertFormattedNumber($rowDatum); - if ($rowDatum !== '' && $this->readFilter->readCell($columnLetter, $currentRow)) { + if (($rowDatum !== '' || $this->preserveNullString) && $this->readFilter->readCell($columnLetter, $currentRow)) { if ($this->contiguous) { if ($noOutputYet) { $noOutputYet = false; @@ -625,4 +630,16 @@ class Csv extends BaseReader return ($encoding === '') ? $dflt : $encoding; } + + public function setPreserveNullString(bool $value): self + { + $this->preserveNullString = $value; + + return $this; + } + + public function getPreserveNullString(): bool + { + return $this->preserveNullString; + } } diff --git a/tests/PhpSpreadsheetTests/Reader/Csv/CsvIssue2840Test.php b/tests/PhpSpreadsheetTests/Reader/Csv/CsvIssue2840Test.php new file mode 100644 index 00000000..34d0a864 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Csv/CsvIssue2840Test.php @@ -0,0 +1,45 @@ +getPreserveNullString()); + $inputData = <<loadSpreadsheetFromString($inputData); + $sheet = $spreadsheet->getActiveSheet(); + self::assertSame($expected, $sheet->toArray()); + $spreadsheet->disconnectWorksheets(); + } + + public function testNullStringLoad(): void + { + $reader = new Csv(); + $reader->setPreserveNullString(true); + $inputData = <<loadSpreadsheetFromString($inputData); + $sheet = $spreadsheet->getActiveSheet(); + self::assertSame($expected, $sheet->toArray()); + $spreadsheet->disconnectWorksheets(); + } +}