Skip to content

Commit e04fcb6

Browse files
committed
add suport for LazyCollections
1 parent 73c7752 commit e04fcb6

18 files changed

+195
-98
lines changed

.github/workflows/php.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ jobs:
1515
uses: php-actions/phpunit@v3
1616
with:
1717
configuration: phpunit.xml.dist
18+
version: 9.5

README.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The memory usage is optimized in this project by retrieving small chunks of resu
1111
This project is using some of Laravel-Excel design principles because it is both a solid work and a reference, and by doing that, it also reduces the learning curve and adoption to this library.
1212

1313
# Requirements
14-
* PHP >= 7.4
14+
* PHP >= 8.0
1515
* Laravel >= 6.x
1616

1717
# Installation
@@ -27,9 +27,9 @@ php artisan vendor:publish --provider="Vitorccs\LaravelCsv\ServiceProviders\CsvS
2727

2828
Step 3) Edit your local `config\csv.php` file per your project preferences
2929

30-
Step 4) Create an Export class file as show below.
30+
Step 4) Create an Export class file as shown below
3131

32-
Note: you may implement _FromArray_, _FromCollection_ or _FromQuery_
32+
Note: you may implement _FromArray_, _FromCollection_ or _FromQuery_
3333

3434
```php
3535
namespace App\Exports;
@@ -77,6 +77,7 @@ $filename = CsvHelper::filename();
7777
```
7878

7979
# Data sources
80+
Note: only `FromQuery` can chunk results per `chunk_size` parameter from config file.
8081

8182
## Laravel Eloquent Query Builder
8283
```php
@@ -121,15 +122,14 @@ class MyQueryExport implements FromQuery
121122
```php
122123
namespace App\Exports;
123124

124-
use Illuminate\Support\Collection;
125125
use Vitorccs\LaravelCsv\Concerns\Exportable;
126126
use Vitorccs\LaravelCsv\Concerns\FromCollection;
127127

128128
class MyCollectionExport implements FromCollection
129129
{
130130
use Exportable;
131131

132-
public function collection(): Collection
132+
public function collection()
133133
{
134134
return collect([
135135
['a1', 'b1', 'c1'],
@@ -140,6 +140,25 @@ class MyCollectionExport implements FromCollection
140140
}
141141
```
142142

143+
## Laravel LazyCollection
144+
```php
145+
namespace App\Exports;
146+
147+
use App\User;
148+
use Vitorccs\LaravelCsv\Concerns\Exportable;
149+
use Vitorccs\LaravelCsv\Concerns\FromCollection;
150+
151+
class MyQueryExport implements FromCollection
152+
{
153+
use Exportable;
154+
155+
public function collection()
156+
{
157+
return User::cursor();
158+
}
159+
}
160+
```
161+
143162
## PHP Arrays
144163
```php
145164
namespace App\Exports;

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
}
1616
],
1717
"require": {
18-
"php": ">=7.4"
18+
"php": ">=8.0"
1919
},
2020
"require-dev": {
2121
"phpunit/phpunit": "^9.5",

src/Concerns/WithMapping.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
interface WithMapping
66
{
77
/**
8-
* @param mixed $row
8+
* @param mixed $row
99
* @return array
1010
*/
1111
public function map($row): array;

src/Helpers/FormatterHelper.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
namespace Vitorccs\LaravelCsv\Helpers;
44

5-
use Carbon\Carbon;
6-
75
class FormatterHelper
86
{
97
/**
10-
* @param Carbon|\DateTime|string $date
8+
* @param \DateTime|string $date
119
* @param string $format
1210
* @return string
1311
*/
@@ -21,7 +19,7 @@ public static function date($date, string $format): string
2119
}
2220

2321
/**
24-
* @param int|float|string $number
22+
* @param float|int|string $number
2523
* @param int $decimals
2624
* @param string $decimalSep
2725
* @param string $thousandsSep

src/Services/ExportableService.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use Vitorccs\LaravelCsv\Concerns\FromArray;
1111
use Vitorccs\LaravelCsv\Concerns\FromCollection;
1212
use Vitorccs\LaravelCsv\Concerns\FromQuery;
13-
use Vitorccs\LaravelCsv\Concerns\FromQueryCursor;
1413
use Vitorccs\LaravelCsv\Entities\CsvConfig;
1514
use Vitorccs\LaravelCsv\Exceptions\InvalidCellValueException;
1615
use Vitorccs\LaravelCsv\Handlers\ArrayHandler;
@@ -63,7 +62,7 @@ public function count(object $exportable): int
6362
return $exportable->collection()->count();
6463
}
6564

66-
if ($exportable instanceof FromQuery || $exportable instanceof FromQueryCursor) {
65+
if ($exportable instanceof FromQuery) {
6766
return $exportable->query()->count();
6867
}
6968

src/Services/FormatterService.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Vitorccs\LaravelCsv\Services;
44

5-
use Carbon\Carbon;
65
use Vitorccs\LaravelCsv\Entities\CsvConfig;
76
use Vitorccs\LaravelCsv\Helpers\FormatterHelper;
87

@@ -22,7 +21,7 @@ public function __construct(CsvConfig $config)
2221
}
2322

2423
/**
25-
* @param Carbon|\DateTime|string $date
24+
* @param \DateTime|string $date
2625
* @return string
2726
*/
2827
public function date($date): string
@@ -31,7 +30,7 @@ public function date($date): string
3130
}
3231

3332
/**
34-
* @param Carbon|\DateTime|string $date
33+
* @param \DateTime|string $date
3534
* @return string
3635
*/
3736
public function datetime($date): string

src/Services/Writer.php

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@
33
namespace Vitorccs\LaravelCsv\Services;
44

55
use Illuminate\Database\Eloquent\Model;
6-
use Illuminate\Support\Collection;
7-
use Throwable;
86
use Vitorccs\LaravelCsv\Concerns\FromArray;
97
use Vitorccs\LaravelCsv\Concerns\FromCollection;
108
use Vitorccs\LaravelCsv\Concerns\FromQuery;
11-
use Vitorccs\LaravelCsv\Concerns\FromQueryCursor;
129
use Vitorccs\LaravelCsv\Concerns\WithColumnFormatting;
1310
use Vitorccs\LaravelCsv\Concerns\WithHeadings;
1411
use Vitorccs\LaravelCsv\Concerns\WithMapping;
@@ -54,11 +51,17 @@ public function generate(object $exportable)
5451

5552
if ($exportable instanceof FromArray) {
5653
$rows = $exportable->array();
54+
if ($exportable->limit()) {
55+
$rows = array_splice($rows, 0, $exportable->limit());
56+
}
5757
$this->iterateRows($exportable, $rows);
5858
}
5959

6060
if ($exportable instanceof FromCollection) {
6161
$rows = $exportable->collection();
62+
if ($exportable->limit()) {
63+
$rows = $rows->take($exportable->limit());
64+
}
6265
$this->iterateRows($exportable, $rows);
6366
}
6467

@@ -72,20 +75,17 @@ public function generate(object $exportable)
7275
);
7376
}
7477

75-
if ($exportable instanceof FromQueryCursor) {
76-
$this->iterateRows($exportable, $exportable->query()->cursor());
77-
}
78-
7978
return $this->handler->getResource();
8079
}
8180

8281
/**
8382
* @param object $exportable
84-
* @param Collection|array $rows
83+
* @param iterable $rows
8584
* @return void
8685
* @throws InvalidCellValueException
8786
*/
88-
private function iterateRows(object $exportable, $rows): void
87+
private function iterateRows(object $exportable,
88+
iterable $rows): void
8989
{
9090
$formats = $exportable instanceof WithColumnFormatting ? $exportable->columnFormats() : [];
9191
$withMapping = $exportable instanceof WithMapping;
@@ -98,7 +98,11 @@ private function iterateRows(object $exportable, $rows): void
9898
}
9999
}
100100

101-
private function normalizeRow($row): array
101+
/**
102+
* @param mixed $row
103+
* @return array
104+
*/
105+
private function normalizeRow(mixed $row): array
102106
{
103107
if ($row instanceof Model) {
104108
$row = ModelHelper::toArrayValues($row);
@@ -113,12 +117,18 @@ private function normalizeRow($row): array
113117
}
114118

115119
/**
120+
* @param array $row
121+
* @param array $formats
122+
* @param int $rowIndex
123+
* @return array
116124
* @throws InvalidCellValueException
117125
*/
118-
private function applyFormatting(array $row, array $formats, int $rowIndex): array
126+
private function applyFormatting(array $row,
127+
array $formats,
128+
int $rowIndex): array
119129
{
120130
return array_map(
121-
fn ($value, int $columnIndex) => $this->formatCellValue($value, $formats, $rowIndex, $columnIndex),
131+
fn($value, int $columnIndex) => $this->formatCellValue($value, $formats, $rowIndex, $columnIndex),
122132
$row,
123133
array_keys($row)
124134
);
@@ -127,7 +137,10 @@ private function applyFormatting(array $row, array $formats, int $rowIndex): arr
127137
/**
128138
* @throws InvalidCellValueException
129139
*/
130-
private function formatCellValue($value, array $formats, int $rowIndex, int $columnIndex): string
140+
private function formatCellValue(mixed $value,
141+
array $formats,
142+
int $rowIndex,
143+
int $columnIndex): string
131144
{
132145
$columnLetter = CsvHelper::getColumnLetter($columnIndex + 1);
133146
$format = $formats[$columnLetter] ?? null;
@@ -149,10 +162,10 @@ private function formatCellValue($value, array $formats, int $rowIndex, int $col
149162
}
150163

151164
try {
152-
if (! is_string($value)) {
165+
if (!is_string($value)) {
153166
return (string)$value;
154167
}
155-
} catch (Throwable $e) {
168+
} catch (\Throwable $e) {
156169
throw new InvalidCellValueException("{$columnLetter}{$rowIndex}");
157170
}
158171

tests/Concerns/FromCollectionTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@
22

33
namespace Vitorccs\LaravelCsv\Tests\Concerns;
44

5+
use Vitorccs\LaravelCsv\Tests\Data\Database\Seeders\TestUsersSeeder;
56
use Vitorccs\LaravelCsv\Tests\Data\Exports\FromCollectionExport;
7+
use Vitorccs\LaravelCsv\Tests\Data\Exports\FromCursorExport;
68
use Vitorccs\LaravelCsv\Tests\TestCase;
79

810
class FromCollectionTest extends TestCase
911
{
1012
protected string $filename = 'from_collection.csv';
1113

14+
protected function setUp(): void
15+
{
16+
parent::setUp();
17+
18+
$this->seed(TestUsersSeeder::class);
19+
}
20+
1221
public function test_from_collection()
1322
{
1423
$export = new FromCollectionExport();
@@ -18,4 +27,14 @@ public function test_from_collection()
1827

1928
$this->assertEquals($export->toArray(), $contents);
2029
}
30+
31+
public function test_from_cursor()
32+
{
33+
$export = new FromCursorExport();
34+
35+
$export->store($this->filename);
36+
$contents = $this->readFromDisk($this->filename);
37+
38+
$this->assertEquals($export->toArray(), $contents);
39+
}
2140
}

tests/Concerns/FromQueryCursorTest.php

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)