Bagaimana cara membuat dan mendownload file csv dari script php?

89

Saya seorang programmer pemula dan saya banyak mencari tentang pertanyaan saya tetapi tidak dapat menemukan solusi atau tutorial yang bermanfaat tentang ini.

Tujuan saya adalah saya memiliki array PHP dan elemen array ditampilkan dalam daftar di halaman.

Saya ingin menambahkan opsi, sehingga jika pengguna mau, dia dapat membuat file CSV dengan elemen array dan mendownloadnya.

Saya tidak tahu bagaimana melakukan ini. Saya telah mencari banyak juga. Namun belum menemukan sumber daya yang bermanfaat.

Tolong berikan saya beberapa tutorial atau solusi atau saran untuk menerapkannya sendiri. Karena saya seorang pemula, berikan solusi yang mudah diterapkan.

Array saya terlihat seperti:

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] => 
        )

)
pengguna2302780
sumber
2
phpExcel untuk file CSV agak terlalu banyak .. php.net/manual/en/function.fputcsv.php
Damien Pirsy
Tunjukkan struktur array Anda dan saya berikan beberapa kode untuk mengubah elemen menjadi csv
setengah cepat
@ setengah cepat Saya telah menambahkan struktur array di pos
user2302780
2
bagaimana cara menambahkan judul kolom di file csv?
pengguna2302780
kemungkinan duplikat Ekspor ke CSV melalui PHP
Michal Mau

Jawaban:

200

Anda dapat menggunakan built in fputcsv () untuk array Anda untuk menghasilkan baris csv yang benar dari array Anda, jadi Anda harus mengulang dan mengumpulkan baris, seperti ini:

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

Untuk membuat browser menawarkan dialog "Simpan sebagai", Anda harus mengirim header HTTP seperti ini (lihat lebih lanjut tentang header ini di rfc ):

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

Menyatukan semuanya:

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

Dan Anda bisa menggunakannya seperti ini:

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"
);

Pembaruan:
Daripada php://memoryAnda juga dapat menggunakan php://outputuntuk deskriptor file dan menghapus pencarian dan semacamnya:

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);
    }
}   
kompleks857
sumber
2
mengapa tidak echogaris CSV yang dihasilkan langsung di loop?
Alex Shesterov
1
@AlexShesterov, alasan utamanya adalah karena fputcsv()tidak mengembalikan baris yang dihasilkan, itu akan memerlukan deskriptor file untuk menulis. Anda dapat memundurkan, menulis, menghapus buffer pada setiap iterasi meskipun jika memori Anda terbatas. Atau gunakan saja file sementara yang sebenarnya.
kompleks857
@ complex857 bagaimana cara menambahkan judul kolom untuk csv?
pengguna2302780
@ user2302780: Anda cukup memberi awalan pada data Anda dengan sebaris nama kolom. Anda dapat menggunakan kunci dari array data dengan sesuatu seperti$data = array_merge(array(array_keys($data[0])), $data);
complex857
1
@JoseRojas yang diharapkan karena begitu Anda meletakkan sesuatu di atas kabel (bahwa apa yang menghasilkan sesuatu dengan php berarti secara konseptual) Anda tidak dapat kembali ke sana. Untuk menggunakan, php://outputlihat contoh kode kedua yang diperbarui.
kompleks857
18

Saya tidak punya cukup reputasi untuk membalas solusi @ complex857. Ini bekerja dengan baik, tetapi saya harus menambahkan; di akhir tajuk Content-Disposition. Tanpanya browser menambahkan dua tanda hubung di akhir nama file (misalnya alih-alih "export.csv" file akan disimpan sebagai "export.csv--"). Mungkin mencoba membersihkan \ r \ n di akhir baris header.

Baris yang benar akan terlihat seperti ini:

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

Jika CSV memiliki karakter UTF-8 di dalamnya, Anda harus mengubah encoding ke UTF-8 dengan mengubah baris Jenis Konten:

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

Juga, saya merasa lebih elegan menggunakan rewind () daripada fseek ():

rewind($f);

Terima kasih atas solusinya!

Luxian
sumber
2
Saya sendiri tidak pernah mengalami bagian --akhir nama file, namun saya telah memperbarui jawabannya (mengapa tidak mengirimkan suntingan saja?)
complex857
14

Coba ... 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();
?>
Indrajeet Singh
sumber
akan rusak jika nilai bidang berisi, itulah mengapa saya lebih suka tsv (tab lebih jarang daripada, dan kami dapat menggantinya atau sesuatu)
oriadam
14

Itu adalah fungsi yang saya gunakan untuk proyek saya, dan berfungsi seperti yang diharapkan.

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();
}
Sajidur Rahman
sumber
1
Saya mengalami kesulitan mencoba menerapkannya di hook send_headers wordpress, karena setiap kali menambahkan semua halaman html saat ini ke akhir file csv. Jawaban ini membuat saya banyak hal, tetapi saya menggunakannya tanpa operasi buffer.
Oleg Apanovich
buffer keluaran bersih memecahkan bagi saya masalah bahwa sebelum penggunaan baris kode ini di awal dan di akhir file yang terbentuk adalah baris kosong.
Sharunas Bielskis
8

Gunakan kode di bawah ini untuk mengubah array php menjadi 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);
Kiran Reddy
sumber
3

Jika struktur array Anda akan selalu multi-dimensi dengan cara yang persis seperti itu, maka kita dapat melakukan iterasi melalui elemen seperti:

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

Itulah salah satu cara untuk melakukannya ... Anda dapat melakukannya secara manual tetapi cara ini lebih cepat dan mudah untuk dipahami dan dibaca.

Kemudian Anda akan mengelola header Anda sesuatu yang dilakukan complex857 untuk mengeluarkan file. Anda kemudian dapat menghapus file menggunakan unlink () jika Anda tidak lagi membutuhkannya, atau Anda dapat meninggalkannya di server jika Anda mau.

setengah cepat
sumber
-2

Gunakan yang berikut ini,

echo "<script type='text/javascript'> window.location.href = '$file_name'; </script>";
Ashwin Balani
sumber