The League of Extraordinary Packages

Our Packages:

Presented by The League of Extraordinary Packages

Getting Started

Connections Settings

Inserting Records

Selecting Records

Interoperability

Converting Records

Upgrading Guide

CSV document output

Once your CSV document is loaded, you can print or enable downloading it using the methods below.

The output methods are affected by the output BOM sequence and/or the supplied PHP stream filters.

Even though you can use the following methods with the League\Csv\Writer object. It is recommended to do so with the League\Csv\Reader class to avoid losing the file cursor position and getting unexpected results when inserting new data.

Printing the document

Returns the string representation of the CSV document

<?php

public AbstractCsv::getContent(void): string
public AbstractCsv::__toString(void): string

The getContent method is added in version 9.1.0 and replaces the __toString method

Use the getContent method to return the CSV full content.

Example

<?php

use League\Csv\Reader;

$reader = Reader::createFromPath('/path/to/my/file.csv', 'r');
echo $reader->getContent();

Exceptions and Errors

If the CSV document is not seekable a Exception or a RuntimeException may be thrown when using getContent. A Fatal Error will be trigger when using the __toString method.

Using the getContent method

<?php

use League\Csv\Writer;

$csv = Writer::createFromFileObject('php://output', 'w');
$csv->insertOne(['foo', 'bar']);
echo $csv->getContent();
//throws an RuntimeException because the SplFileObject is not seekable

Using the __toString method

<?php

use League\Csv\Writer;

$csv = Writer::createFromFileObject('php://output', 'w');
$csv->insertOne(['foo', 'bar']);
echo $csv;
//throws a Fatal Error because no exception can be thrown by the __toString method

The __toString method is deprecated in version 9.1.0 and will be remove in the next major version.

Downloading the document

To make your CSV document downloadable use the output method to force the use of the output buffer on the CSV content.

<?php

public AbstractCsv::output(string $filename = null): int

The method returns the number of characters read from the handle and passed through to the output.

The output method can take an optional argument $filename. When present you can even remove more headers.

Default usage

<?php

use League\Csv\Reader;

header('Content-Type: text/csv; charset=UTF-8');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="name-for-your-file.csv"');

$reader = Reader::createFromPath('/path/to/my/file.csv', 'r');
$reader->output();
die;

Using the $filename argument

<?php

use League\Csv\Reader;

$reader = Reader::createFromPath('file.csv');
$reader->output("name-for-your-file.csv");
die;

If you just need to make the CSV downloadable, end your script with a call to exit just after the output method. You should not return the method returned value.

starting with version 9.1.0, the output method will throw an Exception if the provided $filename does not comply with RFC6266

Outputting the document into chunks

<?php

public AbstractCsv::chunk(int $length): Generator

The AbstractCsv::chunk method takes a single $length parameter specifying the number of bytes to read from the CSV document and returns a Generator to ease outputting large CSV files.

if the $length parameter is not a positive integer a OutOfRangeException will be thrown.

<?php

use League\Csv\Reader;

header('Transfer-Encoding: chunked');
header('Content-Encoding: none');
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="name-for-your-file.csv"');

$reader = Reader::createFromPath('/path/to/huge/file.csv', 'r');
foreach ($reader->chunk(1024) as $chunk) {
    echo dechex(strlen($chunk))."\r\n$chunk\r\n";
}
echo "0\r\n\r\n";

Using a Response object (Symfony, Laravel, PSR-7 etc)

To avoid breaking the flow of your application, you should create a Response object when applicable in your framework. The actual implementation will differ per framework, but you should generally not output headers directly.

<?php

use League\Csv\Reader;

$reader = Reader::createFromPath('/path/to/my/file.csv', 'r');
return new Response((string) $reader, 200, [
    'Content-Encoding' => 'none',
    'Content-Type' => 'text/csv; charset=UTF-8',
    'Content-Disposition' => 'attachment; filename="name-for-your-file.csv"',
    'Content-Description' => 'File Transfer',
]);

In some cases you can also use a Streaming Response for larger files.
The following example uses Symfony’s StreamedResponse object.

Be sure to adapt the following code to your own framework/situation. The following code is given as an example without warranty of it working out of the box.

<?php

use League\Csv\Writer;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;

//We generate the CSV using the Writer object
//$dbh is a PDO object
$stmt = $dbh->prepare("SELECT * FROM users");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
$csv = Writer::createFromPath('php://temp', 'r+');
$csv->insertAll($stmt);

//we create a callable to output the CSV in chunk
//with Symfony StreamResponse you can flush the body content if necessary
//see Symfony documentation for more information
$flush_threshold = 1000; //the flush value should depend on your CSV size.
$content_callback = function () use ($csv, $flush_threshold) {
    foreach ($csv->chunk(1024) as $offset => $chunk) {
        echo $chunk;
        if ($offset % $flush_threshold === 0) {
            flush();
        }
    }
};

//We send the CSV using Symfony StreamedResponse
$response = new StreamedResponse();
$response->headers->set('Content-Encoding', 'none');
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');

$disposition = $response->headers->makeDisposition(
    ResponseHeaderBag::DISPOSITION_ATTACHMENT,
    'name-for-your-file.csv'
);

$response->headers->set('Content-Disposition', $disposition);
$response->headers->set('Content-Description', 'File Transfer');
$response->setCallback($content_callback);
$response->send();

Notes

The output methods can only be affected by:

No other method or property have effect on them.