I know this isn't a pretty solution but you could use the Maatwebsite to export a CSV, save a copy then convert it to XML
https://stackoverflow.com/a/4853122/4046347
Or you would write a script of your own to parse the CSV into an XML file.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi.
I'm looking for the best way to let users export and download data in xml and csv formats.
I have found maatwebsite package to export excel and csv file formats, but it doesn't provide xml.
what do you guys recommend? why packages don't export xml? is it different?
I know this isn't a pretty solution but you could use the Maatwebsite to export a CSV, save a copy then convert it to XML
https://stackoverflow.com/a/4853122/4046347
Or you would write a script of your own to parse the CSV into an XML file.
I've never used this package, but it seems like it could be as simple as:
If you already have the csv:
$formatter = Formatter::make($csvString, Formatter::CSV);
$xml = $formatter->toXml();
Or create both from something like an array:
$formatter = Formatter::make($array, Formatter::ARR);
$csv = $formatter->toCsv();
$xml = $formatter->toXml();
@TALINON - yeah I found this, and already added to my project.
there are two things:
FIRST: In order to this Package to work correctly, I have to prepare the array like this:
$array = [
['firstname' => 'john', 'lastname' => 'trump'],
['firstname' => 'july', 'lastname' => 'william'],
['firstname' => 'jack', 'lastname' => 'johnson'],
];
I have a collection, and when i convert it to array using this:
$arrayList = $people->pluck('person.lastname', 'firstname')->toArray();
the array is like this:
array:3 [▼
"john" => "trump"
"Ajuly" => "william"
"jack" => "johnson"
]
what function should I use instead of pluck function to get the array correctly? as you see I'm getting the last name using relationships.
SECOND: when I solve the first problem, what laravel functions should use to save the output in a file and force the browser to download it without closing the page which the user is on?
Thanks,
The easiest way to prepare your array would be to only get the specific columns you want at the time of the query:
$users = User::get(['firstname', 'lastname'])->toArray();
As for forcing a download of the generated file, I think this would work:
return Response::download($xmlFile, 'export.xml', ['Content-Type: text/xml']);
@KIASATY - You could use
->map(function ($value, $key) { return ['firstname' => $key, 'lastname' => $value]; });
after pluck() and about downloading
return response()->download($formatter->toCsv());
i think it should do it.
Another way of going about it from an existing collection:
$preparedArray = $users->map->only(['firstname', 'lastname'])->toArray();
@TALINON - I'm using relationships. last name is retrieved from another table. so it should be like this:
$users = User::get(['firstname', 'user.lastname'])->toArray();
but user.lastname retrieves null ;/ I think get function does not support relationships!? /:
@TALINON - this retrieves this:
array:7 [▼
3 => array:2 [▶]
0 => array:2 [▶]
6 => array:2 [▶]
5 => array:2 [▶]
2 => array:2 [▶]
1 => array:2 [▶]
4 => array:2 [▶]
]
look at the indexes. it shouldn't be associated array in order to the package work currectly. another problem is that in the array user.lastname is null. problem with relationship.
but this is exactly the structure that is needed. only if 2 problems that i mentioned are solved...
@POXUCIS - look at the output array:
array:4 [▼
"lastname1" => array:2 [▶]
"lastname2" => array:2 [▶]
"lastname3" => array:2 [▶]
"lastname4" => array:2 [▶]
]
both first name and last name are retrieved in the child array. but in dont want the parent array to be associated array. as you see last name is mentioned as key. it should be like this:
array:4 [▼
0 => array:2 [▶]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
]
For your first problem, you have another table for user other than the User model? I'm confused on what is going on there, but at any rate, you can fix that with a join (or just use the map() collection method above on whatever collection you're dealing with.
For the join:
$users = User::join('other_table', 'users.id', '=', 'other_table.id')->get(['firstname', 'other_table.lastname']);
As for the associative array, you can use keyBy()
$users->keyBy('whatever_key')->toArray();
Sorry - I just read your previous post again.. you're saying there shouldn't be an associative array.
You can use ->values()
@TALINON - why
return response()->download($filePath)->deleteFileAfterSend();
works, but
return Storage::download($filePath);
throws this exception: "File not found at path: E:/Project/storage/app/public/report.csv"
Have you sym-linked your storage? php artisan storage:link
Make sure you're using the right disk as well.
return Storage::disk('local')->download($filePath); // for example
and also check your settings within config/filesystems.php
@TALINON - Thanks a lot, I'm gonna test them. I should go deeply through the document to fully understand the logic.
firstname and lastname are examples. I guess there are not good examples obviously. my data is different. there are two models, and "lastname" example is a foreign key in the first model.
I tried to install the soapbox/laravel-formatter package in LAravel 6.9, but that gave a bunch of errors as this package hasn't been updated to use in Laravel 6.9
Have you thought about using the very good Larave-Excel package ?
https://docs.laravel-excel.com/3.1/exports/export-formats.html
Please or to participate in this conversation.