DEV Community

Noriko Yamamoto
Noriko Yamamoto

Posted on

How to download a CSV file with Slim 4

It's a sample code for CSV download with Slim 4.

<?php
declare(strict_types=1);

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class DownloadCsvFIle extends Action
{
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $args): ResponseInterface
    {
        $csv_file = '/path-to-the-csv-file/csvfilename.csv';

        $response = $response
            ->withHeader('Content-Type', 'application/octet-stream')
            ->withHeader('Content-Disposition', 'attachment; filename=csvfilename.csv')
            ->withAddedHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
            ->withHeader('Cache-Control', 'post-check=0, pre-check=0')
            ->withHeader('Pragma', 'no-cache')
            ->withBody((new \Slim\Psr7\Stream(fopen($csv_file, 'rb'))));

        return $response;
    }
}
Enter fullscreen mode Exit fullscreen mode

keyword: slim, slim4, psr-7, csv, download, file download, stream

Top comments (4)

Collapse
 
ryannerd profile image
Ryan Jentzsch

Thank you! Thank you! Thank you!
Why is this not documented in the official Slim 4 docs? This was driving me bonkers. The code below shows how you can send a string as a download (I'm using Eloquent to load a blob from a DB so I don't have a file per se as the file content loads as a string). In this situation change the withBody segment as:

->withBody(
    (new StreamFactory())->createStream($stringContentToDownload)
);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
nixoncode profile image
Nixon Kosgei • Edited

Here is how to echo directly from an array instead of a file


$fileName = uniqid() . 'data.csv';


$headers = ['Name', 'Email', 'Message'];
$data = [
    ['name' => 'nixon kosgei', 'email' => 'nixon@dev.to', 'message' => 'Hello World'],
    ['name' => 'Nelon Tim', 'email' => 'nelon@dev.to', 'message' => 'Keep looking up'],
];

$response->write(implode(',', $headers) . PHP_EOL);


foreach ($data as $datum) {
    $response->write("{$datum['name']},{$datum['email']}, {$datum['message']},\n");
}

return $response->withHeader('Content-Type', 'application/octet-stream')
    ->withHeader('Content-Disposition', "attachment; filename=$fileName")
    ->withAddedHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
    ->withHeader('Cache-Control', 'post-check=0, pre-check=0')
    ->withHeader('Pragma', 'no-cache');
Enter fullscreen mode Exit fullscreen mode

P.S. use this for small datasets only

Collapse
 
mrms profile image
Martin Sjåstad

Where do you get \Slim\Psr7\Stream from ?

Collapse
 
nixoncode profile image
Nixon Kosgei

check it out here github.com/slimphp/Slim-Psr7