digitaldream/data-converter
digitaldream/data-converter is a lightweight Laravel/PHP package offering helpers for converting data between common structures and formats. It aims to simplify routine transformation tasks in your application; see the repository for supported conversions and usage examples.
The package is a thin conversion layer, so the fastest path to productivity is to read the source before you read any docs — with 6 stars and no dependents, the README is likely incomplete and the code is the contract.
Install and register
composer require digitaldream/data-converter
Laravel's package discovery should register the service provider automatically. If not, add it to config/app.php. Check the repo's composer.json for the exact namespace (DigitalDream\DataConverter vs DigitalDreams\DataConverter) — this is the first thing that trips people up on small packages.
Confirm what it actually converts List the public methods on the main class:
php artisan tinker
>>> array_map(fn($m) => $m->getName(), (new ReflectionClass(\DigitalDream\DataConverter\DataConverter::class))->getMethods(\ReflectionMethod::IS_PUBLIC));
Expect something in the shape of arrayToExcel(), excelToArray(), csvToArray(), arrayToCsv(). The exact signatures are what matter — whether they return a path, a streamed response, or a PhpSpreadsheet object.
First use case: a one-shot import The lowest-risk, highest-value entry point is reading an uploaded spreadsheet into a plain array so you can validate it with standard Laravel validators:
$rows = DataConverter::excelToArray($request->file('import')->getRealPath());
$validated = Validator::make(['rows' => $rows], [
'rows' => 'required|array|min:1',
'rows.*.0' => 'required|email',
])->validate();
Run this against a small (≤50 row) fixture first. You'll learn the package's header-row and type-coercion behavior in one pass.
Wrap it, don't sprinkle it. Because the package is a dependency you'll likely outgrow (or need to replace), put every call behind your own service:
final class SpreadsheetService
{
public function toArray(string $path): array
{
return DataConverter::excelToArray($path);
}
public function download(array $rows, string $name): StreamedResponse
{
return DataConverter::arrayToExcel($rows, $name);
}
}
That gives you one seam to swap in maatwebsite/excel or PhpSpreadsheet directly if the package stalls.
Export pattern — build rows from a query, not from models. Convert to a flat array first so the package never sees Eloquent objects:
$rows = Order::query()
->select('id', 'reference', 'total', 'created_at')
->cursor()
->map(fn ($o) => [$o->id, $o->reference, $o->total, $o->created_at->toDateTimeString()])
->all();
return app(SpreadsheetService::class)->download($rows, 'orders.xlsx');
Import pattern — stage, then validate, then persist. Never write to the database inside the parse loop. Read to array → validate the whole payload → DB::transaction() → insert in chunks. This keeps failures atomic and makes the spreadsheet's messy data a validation problem rather than a data-integrity problem.
Push large conversions off-request. Anything above a few thousand rows belongs in a queued job writing to storage/app/, with the download served from there. Small packages like this rarely stream efficiently, and you don't want an OOM in a web worker.
Integration tip: if you're combining with Laravel Excel later, make the import/export classes the interface and have the package be one implementation behind it. Migrating then becomes a one-file change.
StreamedResponse, and a binary string between minor versions. Pin the version in composer.json ("^1.0" is not enough if the API has churned — check the tag history).[null, null, null] entries and break rows.*.0 => required validation. Filter before validating.1001.0), phone numbers lose leading zeros, and dates may arrive as Excel serials (e.g. 45321) rather than strings. Cast explicitly per column; don't trust the array as-is.max:5120 for KB) and row count; a 20 MB upload can otherwise take a worker down.dd(array_slice($rows, 0, 5)) before touching any downstream code — nine times out of ten the issue is in the parsed data, not your importer.How can I help you explore Laravel packages today?