Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Bi Data Export Laravel Package

cbytedigital/laravel-bi-data-export

A Laravel package for exporting business intelligence data. It provides a simple way to move application data into BI and reporting tools, helping teams prepare datasets for analysis without writing custom export logic.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a 1.0.0 release with a deliberately narrow surface: it exports data to CSV. No import, no other formats, no documented queue or scheduling integration. Treat the first release as a single-purpose utility rather than a data pipeline, and confirm the actual API from the package README and src/ before wiring it in — at 1.0.0 the public class names are the contract you'll be pinned to.

  • composer require the package, then check whether it ships a config file (php artisan vendor:publish --tag=...) or is convention-only. Many small export packages are zero-config.
  • Look first at the package's export entry point (a class or facade method that accepts rows and returns a response or a file path). That one signature tells you whether it streams or builds in memory, which determines everything else.
  • First use case: an admin-only route that downloads a filtered report.
Route::middleware('auth')->get('/reports/orders.csv', function () {
    $orders = Order::query()->where('status', 'paid')->with('customer');

    return app(OrderCsvExport::class)->download($orders);
});

If the package has no download helper, you're composing it yourself with the framework's streamDownload / response()->stream() — wrap whatever the package gives you (header row + row serialization) in that.

Implementation Patterns

Extract the export from the controller. The controller should resolve filters, authorize, and hand off. Put column selection, ordering, and row shaping in a dedicated class so the same export is reusable from a route, a command, and a test.

final class OrderCsvExport
{
    public function columns(): array
    {
        return ['id', 'reference', 'customer', 'total', 'paid_at'];
    }

    public function rows(Builder $query): iterable
    {
        foreach ($query->cursor() as $order) {
            yield [
                $order->id,
                $order->reference,
                $order->customer?->name,
                number_format($order->total / 100, 2, '.', ''),
                $order->paid_at?->toIso8601String(),
            ];
        }
    }
}

Feed it an iterable, not a collection. cursor() (or lazy()) keeps the generator lazy. If the 1.0.0 API only accepts Collection, cap the query with a date range or limit and accept that large exports aren't supported yet — don't assume chunking exists because it isn't in the release notes.

Reuse across delivery channels. One export class, three entry points: HTTP download for interactive use, php artisan orders:export --since=... writing to Storage::disk('exports') for scheduled runs, and a Mailable attaching the file. This is where a tiny package earns its place — the value is in the shared column definition, not the file write.

Schedule the big ones. Anything a user might trigger repeatedly belongs in a queued job or scheduler task that writes to a disk and notifies via mail or a signed temporary URL. Keeps request timeouts out of the picture and gives you a durable artifact.

Test the output, not the package. Assert status, Content-Type: text/csv, Content-Disposition filename, and the parsed rows via a small CSV reader — header count matching a known row's column count catches off-by-one mistakes in column definitions.

$response = $this->actingAs($admin)->get('/reports/orders.csv');
$response->assertOk();
$this->assertStringContainsString('reference,total', $response->streamedContent());

Gotchas and Tips

Delimiter and locale. Comma-separated with a dot decimal separator is the safe default. If your audience is on a European Excel locale, they'll see decimal columns collapse into one. Decide explicitly: either emit ; with a config flag, or document "data import, not Excel double-click."

CSV injection. Any cell beginning with =, +, -, @, tab, or CR is a formula risk when opened in Excel. Customer names and notes are user-controlled. Prefix with ' or strip before writing — the package almost certainly does not do this for you at 1.0.0.

UTF-8 BOM for Excel. Without \xEF\xBB\xBF at the start of the stream, Excel mangles accented characters. Add it in your own wrapper; it's a one-liner and a recurring support ticket otherwise.

Output buffering breaks downloads. A stray newline after ?> or a dd() earlier in the request yields the classic "headers already sent" corruption — the CSV downloads but is full of HTML. If output is garbled, ob_get_level() and any middleware echoing are the first place to look.

N+1 inside the loop. with() the relations your columns touch before iterating, or cursor() will fire a query per row and turn a 2-second export into a 200-second one.

Memory and time limits. Streaming is the difference between working and not. Check memory_get_peak_usage on a 50k-row export in a test; if it climbs linearly, you're buffering and need to cap row counts or wait for a later release.

Pin the version and wrap the call. 1.0.0's API is not yet battle-tested. Isolate every package call behind your export class or a thin adapter so a 1.1 or 2.0 rename is a one-file change. Watch for deprecations in point releases rather than assuming semver safety on the config keys.

Extension points to check before building your own. Look for a formatter/serializer/column-definition hook in the source. If one exists, use it — reimplementing row shaping outside the package means you own the header/row alignment problem forever.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log