Skip to content

Commit d92e3b5

Browse files
authored
Merge pull request #178 from brodos/add-xlsx-options-helpers
Add XLSX option helpers to SimpleExcelReader
2 parents 5822cdb + 6713639 commit d92e3b5

5 files changed

+80
-9
lines changed

README.md

+28-8
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ $rows = SimpleExcelReader::create($pathToXlsx)
135135

136136
If you want to check if a sheet exists, use the `hasSheet()` method.
137137

138-
```php
138+
```php
139139
$hasSheet = SimpleExcelReader::create($pathToXlsx)
140140
->hasSheet("sheet1");
141141
```
@@ -159,7 +159,7 @@ If your file has headers that are not on the first line, you can use the `header
159159
to indicate the line at which the headers are present. Any data above this line
160160
will be discarded from the result.
161161

162-
`headerOnRow` accepts the line number as an argument, starting at 0. Blank lines are not counted.
162+
`headerOnRow` accepts the line number as an argument, starting at 0. Blank lines are not counted.
163163

164164
Since blank lines will not be counted, this method is mostly useful for files
165165
that include formatting above the actual dataset, which can be the case with Excel files.
@@ -291,6 +291,26 @@ $rows = SimpleExcelReader::create($pathToXlsx)
291291
->getRows();
292292
```
293293

294+
#### Preserve date formatting
295+
296+
By default, when reading a spreadsheet with dates or times, the values are returned as `DateTimeImmutable` objects. To return a formatted date (e.g., “9/20/2024”) instead, use the `preserveDateTimeFormatting` method. The date format will match what’s specified in the spreadsheet.
297+
298+
```php
299+
$rows = SimpleExcelReader::create($pathToXlsx)
300+
->preserveDateTimeFormatting()
301+
->getRows();
302+
```
303+
304+
#### Preserve empty rows
305+
306+
You can preserve empty rows by using the `preserveEmptyRows` method.
307+
308+
```php
309+
$rows = SimpleExcelReader::create($pathToXlsx)
310+
->preserveEmptyRows()
311+
->getRows();
312+
```
313+
294314
### Writing files
295315

296316
Here's how you can write a CSV file:
@@ -367,12 +387,12 @@ foreach (range(1, 10_000) as $i) {
367387
'first_name' => 'John',
368388
'last_name' => 'Doe',
369389
]);
370-
390+
371391
if ($i % 1000 === 0) {
372392
flush(); // Flush the buffer every 1000 rows
373393
}
374394
}
375-
395+
376396
$writer->toBrowser();
377397
```
378398

@@ -383,7 +403,7 @@ use Spatie\SimpleExcel\SimpleExcelWriter;
383403
use OpenSpout\Common\Entity\Row;
384404

385405
$writer = SimpleExcelWriter::streamDownload('user-list.xlsx', function ($writerCallback, $downloadName) {
386-
406+
387407
$writerCallback->openToBrowser($downloadName);
388408

389409
$writerCallback->addRow(Row::fromValues([
@@ -467,7 +487,7 @@ $border = new Border(
467487
new BorderPart(Border::RIGHT, Color::LIGHT_BLUE, Border::WIDTH_THIN, Border::STYLE_SOLID),
468488
new BorderPart(Border::TOP, Color::LIGHT_BLUE, Border::WIDTH_THIN, Border::STYLE_SOLID)
469489
);
470-
490+
471491
$style = (new Style())
472492
->setFontBold()
473493
->setFontSize(15)
@@ -514,14 +534,14 @@ $writer = SimpleExcelWriter::create($pathToXlsx);
514534

515535
Posts::all()->each(function (Post $post) use ($writer) {
516536
$writer->nameCurrentSheet($post->title);
517-
537+
518538
$post->comments->each(function (Comment $comment) use ($writer) {
519539
$writer->addRow([
520540
'comment' => $comment->comment,
521541
'author' => $comment->author,
522542
]);
523543
});
524-
544+
525545
if(!$post->is($posts->last())) {
526546
$writer->addNewSheetAndMakeItCurrent();
527547
}

src/SimpleExcelReader.php

+27-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use OpenSpout\Reader\ReaderInterface;
1313
use OpenSpout\Reader\RowIteratorInterface;
1414
use OpenSpout\Reader\SheetInterface;
15+
use OpenSpout\Reader\XLSX\Reader as XLSXReader;
16+
use OpenSpout\Reader\XLSX\Options as XLSXOptions;
1517

1618
class SimpleExcelReader
1719
{
@@ -33,6 +35,7 @@ class SimpleExcelReader
3335
protected int $limit = 0;
3436
protected bool $useLimit = false;
3537
protected CSVOptions $csvOptions;
38+
protected XLSXOptions $xlsxOptions;
3639

3740
public static function create(string $file, string $type = ''): static
3841
{
@@ -42,6 +45,7 @@ public static function create(string $file, string $type = ''): static
4245
public function __construct(protected string $path, protected string $type = '')
4346
{
4447
$this->csvOptions = new CSVOptions();
48+
$this->xlsxOptions = new XLSXOptions();
4549

4650
$this->reader = $this->type ?
4751
ReaderFactory::createFromType($this->type) :
@@ -52,7 +56,11 @@ public function __construct(protected string $path, protected string $type = '')
5256

5357
protected function setReader(): void
5458
{
55-
$options = $this->reader instanceof CSVReader ? $this->csvOptions : null;
59+
$options = match (true) {
60+
$this->reader instanceof CSVReader => $this->csvOptions,
61+
$this->reader instanceof XLSXReader => $this->xlsxOptions,
62+
default => null,
63+
};
5664

5765
$this->reader = empty($this->type) ?
5866
ReaderFactory::createFromFile($this->path, $options) :
@@ -112,6 +120,24 @@ public function useEncoding(string $encoding): self
112120
return $this;
113121
}
114122

123+
public function preserveDateTimeFormatting(): self
124+
{
125+
if ($this->reader instanceof XLSXReader) {
126+
$this->xlsxOptions->SHOULD_FORMAT_DATES = true;
127+
}
128+
129+
return $this;
130+
}
131+
132+
public function preserveEmptyRows(): self
133+
{
134+
if ($this->reader instanceof XLSXReader) {
135+
$this->xlsxOptions->SHOULD_PRESERVE_EMPTY_ROWS = true;
136+
}
137+
138+
return $this;
139+
}
140+
115141
public function trimHeaderRow(string $characters = null): self
116142
{
117143
$this->trimHeader = true;

tests/SimpleExcelReaderTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -618,3 +618,28 @@ function () {
618618
['お名前' => '太郎', 'お名前(フリガナ)' => 'タロウ'],
619619
]);
620620
});
621+
622+
it('can preserve date formatting', function () {
623+
$reader = SimpleExcelReader::create(getStubPath('formatted_dates.xlsx'));
624+
625+
$defaultDates = $reader->getRows()->pluck('created_at')->Toarray();
626+
627+
expect($defaultDates[0])->toBeInstanceOf(DateTimeImmutable::class);
628+
expect($defaultDates[1])->toBeInstanceOf(DateTimeImmutable::class);
629+
630+
$formattedDates = $reader
631+
->preserveDateTimeFormatting()
632+
->getRows()
633+
->pluck('created_at')
634+
->toArray();
635+
636+
expect($formattedDates[0])->toEqual('9/20/2024');
637+
expect($formattedDates[1])->toEqual('9/19/2024');
638+
});
639+
640+
it('can preserve empty rows', function () {
641+
$reader = SimpleExcelReader::create(getStubPath('empty_rows.xlsx'));
642+
643+
expect($reader->getRows()->count())->toBe(2);
644+
expect($reader->preserveEmptyRows()->getRows()->count())->toBe(3);
645+
});

tests/stubs/empty_rows.xlsx

8.81 KB
Binary file not shown.

tests/stubs/formatted_dates.xlsx

8.84 KB
Binary file not shown.

0 commit comments

Comments
 (0)