从Symfony2生成和下载CSV

时间:2016-10-25 09:16:33

标签: symfony csv

我正在尝试在我的Symfony项目中创建一个函数,该函数基于搜索项在数据库上运行查询,检索数据然后生成CSV并下载它。我已经按照一些指南来说明如何做到这一点,虽然功能没有失败,但它似乎也没有用。

这是运行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;

}

我的存储库中的getSearchResults函数:

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();
    }

}

如您所见,如果将$array传递为true,则会返回CSV所需的数组结果。

如果传递了特定的查询字符串,我运行exportCSVAction函数:

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

运行它的页面是一个项目列表,如果传递了's'查询,则会对其进行过滤。如果还传递'export',它将按上述方式运行exportCSVAction

该函数不会抛出任何错误,但它只是不下载文件 - 我不知道如何调试它,因为代码被包装在$response对象中,因此它实际上不会运行直到它得到了回报。

如果有人能对此有所了解,我将不胜感激。

3 个答案:

答案 0 :(得分:1)

我使用 Symfony \ Component \ HttpFoundation \ Response;

这是我的前任:

<?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;
    }

}

当我打电话给&#34; /report/export_customers_data.csv"下载正在自动启动

答案 1 :(得分:0)

你能尝试这样的事吗?

$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;

问题可能在这里:filename =&#34;&#39; .getcwd()。&#39; /csv/jobs-export.csv"&#39; 需要一个字符串,文件名......不是相对路径。

答案 2 :(得分:0)

你可以试试这个:

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

你不需要

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