web-dev-qa-db-ja.com

PHPスクリプトからcsvファイルを作成してダウンロードするにはどうすればよいですか?

私は初心者プログラマーであり、私の質問について多くのことを検索しましたが、これに関する有用な解決策やチュートリアルを見つけることができませんでした。

私の目標は、PHP配列があり、配列要素がページのリストに表示されることです。

ユーザーが必要に応じて、配列要素を含むCSVファイルを作成してダウンロードできるように、オプションを追加します。

これを行う方法がわかりません。私もたくさん検索しました。しかし、まだ有用なリソースを見つけるには。

自分で実装するためのチュートリアル、ソリューション、またはアドバイスを提供してください。私は初心者なので、簡単に実装できるソリューションを提供してください。

私の配列は次のようになります:

Array
(
    [0] => Array
        (
            [fs_id] => 4c524d8abfc6ef3b201f489c
            [name] => restaurant
            [lat] => 40.702692
            [lng] => -74.012869
            [address] => new york
            [postalCode] => 
            [city] => NEW YORK
            [state] => ny
            [business_type] => BBQ Joint
            [url] => 
        )

)
74
user2302780

配列に組み込みの fputcsv() を使用して、配列から正しいcsv行を生成できるため、ループオーバーして行を収集する必要があります。のような:

$f = fopen("tmp.csv", "w");
foreach ($array as $line) {
    fputcsv($f, $line)
}

ブラウザに「名前を付けて保存」ダイアログを提供するには、次のようなHTTPヘッダーを送信する必要があります(このヘッダーの詳細については、 rfc を参照)。

header('Content-Disposition: attachment; filename="filename.csv";');

すべてを一緒に入れて:

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
    // open raw memory as file so no temp files needed, you might run out of memory though
    $f = fopen('php://memory', 'w'); 
    // loop over the input array
    foreach ($array as $line) { 
        // generate csv lines from the inner arrays
        fputcsv($f, $line, $delimiter); 
    }
    // reset the file pointer to the start of the file
    fseek($f, 0);
    // tell the browser it's going to be a csv file
    header('Content-Type: application/csv');
    // tell the browser we want to save it instead of displaying it
    header('Content-Disposition: attachment; filename="'.$filename.'";');
    // make php send the generated csv lines to the browser
    fpassthru($f);
}

そして、次のように使用できます。

array_to_csv_download(array(
  array(1,2,3,4), // this array is going to be the first row
  array(1,2,3,4)), // this array is going to be the second row
  "numbers.csv"
);

更新:
php://memoryの代わりに、ファイル記述子に php://output を使用して、シークなどを廃止することもできます。

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
    header('Content-Type: application/csv');
    header('Content-Disposition: attachment; filename="'.$filename.'";');

    // open the "output" stream
    // see http://www.php.net/manual/en/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq
    $f = fopen('php://output', 'w');

    foreach ($array as $line) {
        fputcsv($f, $line, $delimiter);
    }
}   
165
complex857

@ complex857ソリューションに返信するのに十分な評判がありません。それはうまく機能しますが、追加する必要がありました。 Content-Dispositionヘッダーの最後。これがないと、ブラウザはファイル名の末尾に2つのダッシュを追加します(たとえば、「export.csv」の代わりに、ファイルは「export.csv--」として保存されます)。おそらくヘッダー行の最後で\ r\nをサニタイズしようとします。

正しい行は次のようになります。

header('Content-Disposition: attachment;filename="'.$filename.'";');

CSVにUTF-8文字が含まれる場合、Content-Type行を変更してエンコードをUTF-8に変更する必要があります。

header('Content-Type: application/csv; charset=UTF-8');

また、fseek()の代わりにrewind()を使用する方がよりエレガントです。

rewind($f);

あなたの解決策をありがとう!

13
Luxian
Try...
csv download.
<?php 
mysql_connect('hostname', 'username', 'password');
mysql_select_db('dbname');
$qry = mysql_query("SELECT * FROM tablename");
$data = "";
while($row = mysql_fetch_array($qry)) {
  $data .= $row['field1'].",".$row['field2'].",".$row['field3'].",".$row['field4']."\n";
}

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="filename.csv"');
echo $data; exit();
?>
12
Indrajeet Singh

以下のコードを使用して、PHP配列をCSVに変換します

<?php
   $ROW=db_export_data();//Will return a php array
   header("Content-type: application/csv");
   header("Content-Disposition: attachment; filename=test.csv");
   $fp = fopen('php://output', 'w');

   foreach ($ROW as $row) {
        fputcsv($fp, $row);
   }
   fclose($fp);
7
Kiran Reddy

配列構造が常にその正確な方法で多次元である場合、次のような要素を反復処理できます。

$fh = fopen('somefile.csv', 'w') or die('Cannot open the file');

for( $i=0; $i<count($arr); $i++ ){
    $str = implode( ',', $arr[$i] );
    fwrite( $fh, $str );
    fwrite( $fh, "\n" );
}
fclose($fh);

それはそれを行う1つの方法です...あなたは手動でそれを行うことができますが、この方法はより速く、より簡単に理解して読むことができます。

その後、complex857がファイルを吐き出すために行っていることを、ヘッダーを管理します。不要になった場合はnlink()を使用してファイルを削除できますが、必要に応じてサーバーに残しておくこともできます。

3
half-fast

それが私のプロジェクトに使用した関数であり、期待通りに機能します。

function array_csv_download( $array, $filename = "export.csv", $delimiter=";" )
{
    header( 'Content-Type: application/csv' );
    header( 'Content-Disposition: attachment; filename="' . $filename . '";' );

    // clean output buffer
    ob_end_clean();

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

    // use keys as column titles
    fputcsv( $handle, array_keys( $array['0'] ) );

    foreach ( $array as $value ) {
        fputcsv( $handle, $value , $delimiter );
    }

    fclose( $handle );

    // flush buffer
    ob_flush();

    // use exit to get rid of unexpected output afterward
    exit();
}
2
Sajidur Rahman