1

我有一个模型,它返回带有 ID、名称、价格等的汽车数据。所以我有一个汽车控制器和一个从模型中获取这些数据的 csv 操作:

$carTable = $this->getServiceLocator()->get('Application\Model\DbTable\Cars');
$cars = $carTable->fetchAll();

我需要将此“$cars”数据下载为 CSV 文件,以便用户可以将其存储在磁盘上。

我试图禁用布局并回显 CSV 字符串并设置“内容类型”和其他标题,但它没有开箱即用。然后我发现我可能应该创建一个自定义 CsvRenderer 并在配置中注册它。

由于我在 ZF2 网站或博客和 Stackoverflow 答案中找不到任何关于此的文档,我想知道这是否是在 ZF2 中将数据下载为 CSV 的推荐通用方法?还是有一个我不知道的更简单的解决方案?

谢谢

4

3 回答 3

11

一种解决方案是直接从控制器返回一个响应对象。

这样的事情很有可能奏效:

public function downloadAction()
{
    // magically create $content as a string containing CSV data

    $response = $this->getResponse();
    $headers = $response->getHeaders();
    $headers->addHeaderLine('Content-Type', 'text/csv');
    $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"my_filen.csv\"");
    $headers->addHeaderLine('Accept-Ranges', 'bytes');
    $headers->addHeaderLine('Content-Length', strlen($content));

    $response->setContent($content);
    return $response;
}

(请注意,我尚未测试此代码,但已根据评论进行了更新!)

于 2012-12-03T20:10:55.067 回答
3

既然我们在谈论 ZF2,我宁愿通过添加一个新的 CSV ViewStrategy/Renderer/ViewModel 来解决这个问题。

在这里你可以阅读更多关于实现自己的渲染和响应策略:Zend Docs

甚至在这里:http: //zend-framework-community.634137.n4.nabble.com/ZF2-Implementing-custom-renderer-strategy-td4655896.html

这将使控制器中的代码更苗条、更清晰、更清晰,因为您不必关心控制器中的标头,而是在渲染器中。然后,每次您需要一个新的 CSV 输出时,您不必重新编写该操作,您只需使用 CSV 视图模型

于 2014-02-18T16:42:38.937 回答
2

这是基于 Rob 提供的答案。

在 Rob 的回答中,通过分配$response->getHeaders()给一个新$headers变量,然后将 应用于->addHeaderLine该新变量,它没有正确设置$response. 因此,当返回时,标头未附加到响应中。

要解决此问题,只需将标题直接添加到$response如下所示:

public function downloadAction()
{
    // magically create $content as a string containing CSV data

    $response = $this->getResponse();
    $response->getHeaders()
             ->addHeaderLine('Content-Type', 'text/csv')
             ->addHeaderLine('Content-Disposition', "attachment; filename=\"my_filen.csv\"")
             ->addHeaderLine('Accept-Ranges', 'bytes')
             ->addHeaderLine('Content-Length', strlen($content));

    $response->setContent($content);
    return $response;
}
于 2013-04-11T21:56:24.263 回答