php
47 lines · 8 steps
Streaming a monthly revenue CSV in Laravel
A report service builds a revenue CSV by lazily streaming completed orders, tallying a running total, and writing the file to disk.
Explained by
highlit
1<?php
2
3namespace App\Services\Reports;
4
5use App\Models\Order;
6use Illuminate\Support\Facades\Storage;
7use League\Csv\Writer;
8
9class MonthlyRevenueReport
10{
11 public function generate(string $month): string
12 {
13 $path = "reports/revenue-{$month}.csv";
14 $csv = Writer::createFromString();
15 $csv->insertOne(['order_id', 'customer', 'placed_at', 'net_total', 'tax', 'gross_total']);
16
17 $grossRunningTotal = 0;
18
19 Order::query()
20 ->whereYear('placed_at', substr($month, 0, 4))
21 ->whereMonth('placed_at', substr($month, 5, 2))
22 ->where('status', 'completed')
23 ->with('customer:id,name')
24 ->orderBy('placed_at')
25 ->lazy(1000)
26 ->each(function (Order $order) use ($csv, &$grossRunningTotal): void {
27 $tax = round($order->net_total * $order->tax_rate, 2);
28 $gross = $order->net_total + $tax;
29 $grossRunningTotal += $gross;
30
31 $csv->insertOne([
32 $order->id,
33 $order->customer->name,
34 $order->placed_at->toDateTimeString(),
35 number_format($order->net_total, 2, '.', ''),
36 number_format($tax, 2, '.', ''),
37 number_format($gross, 2, '.', ''),
38 ]);
39 });
40
41 $csv->insertOne(['', '', '', '', 'TOTAL', number_format($grossRunningTotal, 2, '.', '')]);
42
43 Storage::disk('reports')->put($path, $csv->toString());
44
45 return $path;
46 }
47}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Lazy collections let you process large query results in chunks without loading every row into memory at once.
- 2Accumulating a total by reference inside the iteration callback avoids a second pass over the data.
- 3Eager-loading and column selection on relations keep per-row work cheap during a big export.
Related explainers
php
<?php namespace App\Console\Commands;
Releasing stale document locks in Laravel
artisan-command
transactions
row-locking
Intermediate
6 steps
php
<?php namespace App\Providers;
Subdomain multi-tenancy routing in Laravel
multi-tenancy
service-container
route-binding
Advanced
7 steps
php
<?php namespace App\Broadcasting;
Authorizing presence channels in Laravel
broadcasting
authorization
presence-channels
Intermediate
3 steps
php
<?php namespace App\Http\Middleware;
Resolving the current team in Laravel middleware
middleware
multi-tenancy
cookies
Intermediate
8 steps
php
<?php namespace App\Http\Controllers;
Broadcasting typing indicators in Laravel
websockets
authorization
presence-channels
Intermediate
9 steps
php
<?php namespace App\Services;
Computing rolling averages in Laravel
rolling-average
date-ranges
collections
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-a-monthly-revenue-csv-in-laravel-explained-php-e60d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.