4

データベースから .csv にデータをエクスポートしてみます。エクスポート リンクをクリックしても、大量のデータがある場合、ブラウザに保存ウィンドウが長時間表示されません。スクリプトがしばらくハングしているように見え、かなり時間がたつとブラウザに保存ウィンドウが表示されると、非常に混乱する可能性があります。コードはコントローラーで次のようなものです。

$this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender();
        $fileName = $list->list_name . '.csv';

        $this->getResponse()->setHeader('Content-Type', 'text/csv; charset=utf-8')
                            ->setHeader('Content-Disposition', 'attachment; filename="'. $fileName . '"');      

        $contacts = new Contact();
        $contacts->export($listId);

Export メソッドはレコードを 1 つずつ読み取り、次のように出力します。

    $fp = fopen('php://output', 'w');        
    foreach ($mongodbCursor as $subscriber) {
           $row = formRow($subscriber);
       fputcsv($fp, $row);
        }       

一部のアプリケーションでは、保存ウィンドウがすぐに表示され、保存をクリックするとダウンロードの進行状況が表示されます。

私は置き換えようとしました:

    $this->getResponse()->setHeader('Content-Type', 'text/csv; charset=utf-8')
                        ->setHeader('Content-Disposition', 'attachment; filename="'. $fileName . '"');

これで:

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="'. $fileName . '"');

これまでのところ役に立ちませんでした。データベースからすべてのデータを 1 つずつ読み取る前にヘッダーを送信することは可能でしょうか? ご協力ありがとうございます。

4

6 に答える 6

1

うーん、私は php://output に慣れていません。私のアプリケーションは、私の情報を fopen,fwrite,fclose で一時ファイルに書き込んでから、同様の header(); で出力します。オプション。

            $filesize = filesize("tmp/export.csv");
            header("Content-Type: text/csv");
            header("Content-Disposition: attachment; filename=\"export.csv\"");
            header("Conent-Length: $filesize");
            readfile("tmp/export.csv");
            unlink("tmp/export.csv");
            exit;

これにより、ブラウザのダウンロードウィンドウが即座に表示されます。

于 2012-04-12T06:56:22.497 に答える
1

あなたはこれを試みることができます:

  • 代わりにヘッダー関数を呼び出します$this->getResponse()->setHeader()(応答コンテンツはバッファーに保存され、完了したとき (エクスポートが終了したとき) にのみ出力される場合があります)
  • php://output に書き込む代わりに、コンテンツを直接エコーしてみてください (その前にヘッダーを設定すると、エコーするすべてのものが生成された CSV ファイルに配置されます)。

編集

以下fputcsvのような関数に置き換えますprint_row

function print_row($row) {
        echo '"' . implode('","', $row) . '"' . "\r\n"; 
}

この関数は、最初のパラメーターを配列として取得し、コンテンツに"and,と echo を追加します。

于 2012-04-12T06:58:57.903 に答える
0

関数は、長い操作の直前にflush / ob_flushを呼び出し、長いプロセスの前にHTTPヘッダーをクライアントに送信させたい場合があります。

于 2013-01-04T01:53:17.063 に答える
0
// $file = path of file

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;

ソース: http: //php.net/manual/en/function.readfile.php

于 2012-04-12T07:10:31.507 に答える
0

application/force-download値の代わりに使用してみてtext/csvくださいContent-Type

header("Content-Type: application/force-download; name=\"" . $fileName . "\""); 

これにより、ブラウザにコンテンツ表示するだけでなく、実際のダウンロードボックスが強制されます。

MIMEアプリケーションのドキュメントは次のとおりです。

Mimeアプリケーション/force-downloadは、通常mime application / x-force-downloadとして表され、通常、Webブラウザーでコンテンツを表示するためではなく、PHPコードと組み合わせてダウンロードボックスをトリガーするために使用されます。

たとえば、Webブラウザで表示するのではなく、ユーザーにダウンロードしてもらいたいファイルがWebサイトにある場合は、ファイルのヘッダーコンテンツタイプフィールドに適切なmime application/force-downloadコードを入力できます。mime application/force-downloadは登録済みのMIMEタイプではないことに注意してください。さらに、PHPコードで使用する場合、mime application/force-downloadの優先スペルには「x-」プレフィックスが含まれます。

于 2012-04-12T15:52:32.503 に答える
0

これが良い解決策かどうかはわかりません。あまり調べていませんが、機能しているようです。エクスポートする前に、ヘッダーの後にバッファにデータを追加した後、コントローラです。

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="'. $fileName . '"');

    echo str_pad('', ini_get('output_buffering'));      
    ob_flush();
    flush();

    Model_Subscriber1::exportList($listId);

Zend Bootstrap.php に追加したコントローラーで動作させるには:

/**
 * hint to the dispatcher that it should not use output buffering to capture output generated by action controllers.
 *  By default, the dispatcher captures any output and appends it to the response object body content. 
 */
protected function _initFront()
{
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->setParam('disableOutputBuffering', 1);        
}

この場合、ブラウザでダウンロード ウィンドウがすぐに表示され、データがエクスポートされているように見えますが、これにはかなりの時間がかかる可能性があります。この解決策が現在受け入れられるかどうかはわかりません。それについてのご意見をここにいただければ幸いです。空のデータをエクスポート ファイルに追加すると問題が発生します。それで、私はそれをコントローラに変更します。

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="'. $fileName . '"');

    Model_Subscriber1::exportList($listId);

そして、エクスポート用の関数を次のように変更します。

  foreach ($mongodbCursor as $subscriber) {
           $row = formRow($subscriber);
    echo '"' . implode('","', $row) . '"' . "\r\n";
    ob_flush();
    flush();                    

  }       
于 2012-04-20T11:26:35.343 に答える