21

Symfony 2 を使用して「ダウンロード」コントローラーを作成しています。これは、.csv ファイルのダウンロードを強制できるようにヘッダーを送信することを唯一の目的としていますが、正しく機能していません。

$response = new Response();
$response->headers->set('Content-Type', "text/csv");
$response->headers->set('Content-Disposition', 'attachment; filename="'.$fileName.'"');
$response->headers->set('Pragma', "no-cache");
$response->headers->set('Expires', "0");
$response->headers->set('Content-Transfer-Encoding', "binary");
$response->headers->set('Content-Length', filesize($fileName));
$response->prepare();
$response->sendHeaders();
$response->setContent(readfile($fileName));
$response->sendContent();

$fileName"info.csv"文字列です。これはコントローラー内の私のアクションであり、return ステートメントはありません。オブジェクトを返そうとするとResponse、意図した結果ではなく、ファイルの内容がブラウザに表示されました。

私が見つけた問題は、一部のページではinfo.csv file.

No webpage was found for the web address: http://mywebpage.com/download Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.

ファイルが存在すると完全に確信しているので、別のことが間違っているに違いありません。また、そのパスにリンクしている他のページからファイルを取得するため、routing.yml は正しく機能しています。Apache エラー ログには、それについては何も表示されません。

以前に Symfony 2 で .csv ファイルのダウンロードを強制した人はいますか? もしそうなら、私は何を間違っていますか?

4

6 に答える 6

36

本番環境で問題なく動作する最小限の例を次に示します。

class MyController
public function myAction()

    $response = $this->render('ZaysoAreaBundle:Admin:Team/list.csv.php',$tplData);

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

    return $response;

必要に応じて、render 呼び出しを新しい応答と response->setContent に置き換えることができます。

コントローラー内に return ステートメントがないというあなたのコメントは不可解です。コントローラーは応答を返します。フレームワークがブラウザへの送信を処理します。

于 2012-04-25T00:50:54.213 に答える
8

この投稿はちょっと古いもので、奇妙なことに、symfony 2 で CSV エクスポートを行う方法については、stackoverflow のこの投稿以外に良いリソースがほとんどないことに気付きました。

とにかく、上記の例をクライアント コンテスト サイトに使用したところ、非常にうまく機能しました。しかし、今日、私は電子メールを受け取り、自分でテストした後、コードが壊れていました.少量の結果でダウンロードを機能させることができましたが、データベースは現在31,000行以上をエクスポートしており、単にテキストを表示するか、クロム、基本的に何もしませんでした。

大規模なデータのエクスポートに問題がある人のために、これは私が何とか仕事に取り掛かったものであり、基本的にCeradが代替方法として提案したことを行っています:

    $filename = "export_".date("Y_m_d_His").".csv";
    $response = $this->render('AppDefaultBundle:Default:csvfile.html.twig', array('data' => $data));

    $response->setStatusCode(200);
    $response->headers->set('Content-Type', 'text/csv');
    $response->headers->set('Content-Description', 'Submissions Export');
    $response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
    $response->headers->set('Content-Transfer-Encoding', 'binary');
    $response->headers->set('Pragma', 'no-cache');
    $response->headers->set('Expires', '0');

    $response->prepare();
    $response->sendHeaders();
    $response->sendContent();

編集:さらにテストを行い、許可される最大秒数を増やした後、前のコードがヘッダーを上部に出力していることに気付いたので、コードを更新しました。

于 2012-07-02T15:06:04.980 に答える
6

これは、CSV と JSON をエクスポートするのに役立ちました。

Twig ファイルの名前: export.csv.twig、export.json.twig

コントローラー:

class PrototypeController extends Controller {

public function exportAction(Request $request) {

    $data = array("data" => "test");

    $format = $request->getRequestFormat();

    if ($format == "csv") {
        $response = $this->render('PrototypeBundle:Prototype:export.' . $format . '.twig', array('data' => $data));
        $filename = "export_".date("Y_m_d_His").".csv";
        $response->headers->set('Content-Type', 'text/csv');
        $response->headers->set('Content-Disposition', 'attachment; filename='.$filename);

        return $response;
    } else if ($format == "json") {
        return new Response(json_encode($data));
    }
}
}

ルーティング:

prototype_export:
    pattern:  /export/{_format}
    defaults: { _controller: PrototypeBundle:Prototype:export, _format: json }
    requirements:
        _format:  csv|json

小枝:

export.csv.twig (ここでコンマ区切りのことを行います。これは単なるテストです)

{% for row in data %}
{{ row }}
{% endfor %} 

export.json.twig (データは json_encoded で送信され、このファイルは空です)

お役に立てれば!

于 2013-08-26T05:46:14.173 に答える
-1

Sonata の Exporter を使用するのはどうですか:

use Exporter\Writer\CsvWriter;
/**
 * @param array $orders
 */
public function exportToCsv($orders)
{
    $rootdir = $this->get('kernel')->getRootDir();
    $filename = $rootdir . '/data/orders.csv';
    unlink($filename);
    $csvExport = new CsvWriter($filename);
    $csvExport->open();
    foreach ($orders as $order)
    {
        $csvExport->write($order);
    }
    $csvExport->close();
    return;

}

ファイルが既に存在する場合はクラッシュするため、リンク解除コマンドです。

于 2014-10-07T12:14:50.060 に答える