Michael Emerson
Michael Emerson

Reputation: 1813

Generating and downloading a CSV from Symfony2

I'm trying to create a function in my Symfony project that runs a query on the database based on a search term, retrieves the data then generates a CSV and downloads it. I've followed some guides on how to do this and although the function does not fail, it also does not seem to work.

Here is the function that runs the generate csv:

public function exportCSVAction($filter)
{
    $container = $this->container;
    $response = new StreamedResponse(function() use($container,$filter) {

        $em = $container->get('doctrine')->getManager();
        $project_repo = $em->getRepository('AppBundle:Project');

        $results = $project_repo->getSearchResults($filter,true);

        $handle = fopen('php://output', 'w+');

        while (false !== ($row = $results)) {
            fputcsv($handle, $row[0]);
            $em->detach($row[0]);
        }

        fclose($handle);
    });

    $response->headers->set('Content-Type', 'application/force-download');
    $response->headers->set('Content-Disposition','attachment; filename="'.getcwd().'/csv/jobs-export.csv"');

    return $response;

}

The getSearchResults function in my Repository:

public function getSearchResults($filter,$array=false)
{

    $qb = $this->createQueryBuilder('p')
        ->select('p')
        ->leftJoin('AppBundle:Oc73Customer', 'c', 'WITH', 'c.customerId = p.customerId')
        ->leftJoin('AppBundle:Oc73Product', 'pr', 'WITH', 'pr.productId = p.productId')
        ->where('c.firstname LIKE :filter')
        ->orWhere('c.lastname LIKE :filter')
        ->orWhere('pr.model LIKE :filter')
        ->orWhere('p.pONumber LIKE :filter')
        ->setParameter('filter', '%'.$filter.'%');

    if($array == true) {
        return $qb->getQuery()->getArrayResult();
    } else {
        return $qb->getQuery()->getResult();
    }

}

As you can see, if $array is passed as true, it returns an Array result required for the CSV.

I run the exportCSVAction function if a specific query string is passed:

if($request->get('export')) {
      $this->exportCSVAction($request->get('s'));
}

The page it is run on is a list of projects, and is filtered if the 's' query is passed. If 'export' is also passed it runs the exportCSVAction as above.

The function throws no errors, but it just does not download the file - I'm not sure how to debug it since the code is wrapped in a $response object, so it doesn't actually run until it gets returned.

If anyone can shed any light on this I would be grateful.

Upvotes: 2

Views: 6462

Answers (3)

giurgiu rubin
giurgiu rubin

Reputation: 71

i used Symfony\Component\HttpFoundation\Response;

here is my ex:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Customers;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class ReportController extends Controller
{
    /**
     * @Route("/report/export_customers_data.csv", name="export_customers_data_csv")
     */
    public function exportCustomersDataCsvAction()
    {

        $customers = $this->getCustomersFromDatabase();

        $rows = array();
        foreach ($customers as $event) {
            $data = array(
                $event->getId(),
                $event->getcustNameOne(),
                $event->getcustNameTwo(),
                $event->getcustAddress(),
                $event->getcustCountry(),
                $event->getcustBusiness(),
                $event->getcustEmail(),
                $event->getcustPhone(),
                $event->getspecialReq()
            );

            $rows[] = implode(',', $data);
        }

        $content = implode("\n", $rows);
        $response = new Response($content);
        $response->headers->set('Content-Type', 'text/csv');

        return $response;


    }


    public function getCustomersFromDatabase()
    {
        $customers = $this->getDoctrine()
            ->getRepository('AppBundle:Customers')
            ->findAll();

        return $customers;
    }

}

when i call "/report/export_customers_data.csv" the download is starting automaticaly

Upvotes: 2

kodu.cloud
kodu.cloud

Reputation: 1600

You can try this:

$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition','attachment; filename="sample"');

You don`t need

$response->headers->set('Content-Type', 'application/force-download');

Upvotes: 0

Cristian Bujoreanu
Cristian Bujoreanu

Reputation: 1167

Can you try something like this?

$response->headers->set('Content-Encoding', 'UTF-8');
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
$response->headers->set('Content-Disposition', 'attachment; filename=sample.csv');

return $response;

The problem might be here: filename="'.getcwd().'/csv/jobs-export.csv"' A string is expected, the file name...not a relative path.

Upvotes: 0

Related Questions