Warning: You are browsing the documentation for PrestaShop 8, which is outdated.
You might want to read an updated version of this page for the current version, PrestaShop 9. Read the updated version of this page
Introduced in 1.7.3 , this component allows to export data to CSV Format.
To use this component, add a use statement in your module:
use PrestaShopBundle\Component\CsvResponse;
Build your data as an array of lines, and each line is an associative array:
$lines = [
["name" => "My product A", "brand" => "Brand 1", "price" => 2204, "ignored_data" => "abcd"],
["name" => "My product B", "brand" => "Brand 2", "price" => 1399, "ignored_data" => "efgh"],
["name" => "My product C", "brand" => "Brand 3", "price" => 687, "ignored_data" => "ijkl"]
];
Create the headers for your columns:
$headersData = [
"name" => "Product name",
"brand" => "Product brand",
"price" => "Product price"
];
$headersData.Finally, create and return your CsvResponse export:
return (new CsvResponse())
->setHeadersData($headersData)
->setData($lines);
Since CsvResponse extends Symfony\Component\HttpFoundation\StreamedResponse, this will create and send to the browser a Symfony\Component\HttpFoundation\StreamedResponse (which is extended from Symfony\Component\HttpFoundation\Response).
Without any parameter when creating the export, the filename of the export is export_date.csv :
'export_' . date('Y-m-d_His') . '.csv'
When creating / returning the CsvResponse, use setFilename() method to set a specific filename for the export:
return (new CsvResponse())
->setHeadersData($headersData)
->setData($lines)
->setFilename("my_awesome_export.csv");
Sometimes you will need to export large parts of data with a large memory usage, that can cause performance issues. To achieve this, you can’t just query your database and retrieve your large amount of data. You need to chunk your data, and build your csv export chunk by chunk.
Let’s understand how to do this:
callback function, with two parameters: $offset and $limit.$dataCallback = function ($offset, $limit){
$data = $myRepository->getData($offset, $limit);
return $data;
}
This callback function returns a set of data from a repository (eg. a database), with $offset and $limit parameters (eg. a LIMIT 0,5000 SQL query).
callback function as data:return (new CsvResponse())
->setHeadersData($headersData)
->setData($dataCallback);
The default $limit is set to 5000.
You can modify this limit by calling setLimit(int $limit):
return (new CsvResponse())
->setHeadersData($headersData)
->setData($dataCallback)
->setLimit(1000);
Since $dataCallback is a callable, CsvResponse will loop over your callback function when creating the Csv.
There are two modes when retrieving data with a callback function:
CsvResponse::MODE_OFFSET: Your callback function is receiving $offset (index to start retrieving items at) and $limit (count of items to retrieve). This is the equivalent of MySql LIMIT 0,100, LIMIT 100,100, LIMIT 200,100.CsvResponse::MODE_PAGINATION: Your callback function is receiving $offset (page number) and $limit (count of items to retrieve), and will handle its pagination itself.The default mode is MODE_PAGINATION.
When looping over your callback function, the CsvResponse is retrieving $limit items, while there are results.
$offset is starting at 1, and is increased by 1 at each loop. To use this mode, add:
->setModeType(CsvResponse::MODE_PAGINATION)
$offset is starting at 0, and is increased by $limit at each loop. To use this mode, add:
->setModeType(CsvResponse::MODE_OFFSET)
CsvResponse::MODE_OFFSET can be seen in ProductCsvExporter.php$start parameter can be set manually by adding a setStart(int $start) call to your CsvResponse:
return (new CsvResponse())
->setHeadersData($headersData)
->setData($dataCallback)
->setStart($start)
->setLimit($limit)
From
8.0
, to disable header line from export, use the setIncludeHeaderRow() method. This method expects a boolean parameter indicating if the header line should be displayed or not.
return (new CsvResponse())
->setHeadersData($headersData)
->setData($lines)
->setIncludedHeaderRow(false);