PHP betiğinden bir csv dosyası nasıl oluşturulur ve indirilir?


92

Acemi bir programcıyım ve sorumla ilgili çok araştırma yaptım ancak bu konuda yardımcı bir çözüm veya öğretici bulamadım.

Amacım bir PHP dizim var ve dizi öğeleri sayfadaki bir listede gösteriliyor.

Bir seçenek eklemek istiyorum, böylece bir kullanıcı isterse, dizi öğeleriyle bir CSV dosyası oluşturabilir ve indirebilir.

Bunu nasıl yapacağımı bilmiyorum. Ben de çok araştırdım. Ancak henüz yararlı bir kaynak bulamadık.

Lütfen bunu kendi başıma uygulamak için bana biraz eğitim veya çözüm veya tavsiye sağlayın. Acemi olduğum için lütfen uygulaması kolay çözümler sağlayın.

Dizim şöyle görünüyor:

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

)

2
Bir CSV dosyası için phpExcel biraz fazla .. php.net/manual/en/function.fputcsv.php
Damien Pirsy

Dizi yapınızı gösterin ve öğeleri bir csv'ye dönüştürmek için bazı kodlar sağlayın
yarı hızlı

@ half-fast
Yazıya

2
csv dosyasında sütun başlığı nasıl eklenir?
user2302780

Yanıtlar:


208

Dizinizden doğru csv satırları oluşturmak için dizileriniz için yerleşik fputcsv () işlevini kullanabilirsiniz , bu nedenle aşağıdaki gibi satırları döngüye alıp toplamanız gerekir:

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

Tarayıcıların "Farklı Kaydet" iletişim kutusunu sunmasını sağlamak için, bunun gibi HTTP başlıklarını göndermeniz gerekir ( rfc'de bu başlık hakkında daha fazla bilgi edinin ):

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

Hepsini bir araya koy:

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

Ve bunu şu şekilde kullanabilirsiniz:

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

Güncelleme:
Bunun yerine dosya tanımlayıcısı için php://memoryde kullanabilir php://outputve arama ve benzeri şeyleri ortadan kaldırabilirsiniz :

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

2
neden echooluşturulan CSV hatları doğrudan döngüde değil?
Alex Shesterov

1
@AlexShesterov'un ana nedeni, fputcsv()oluşturulan satırı döndürmemesi, yazmak için bir dosya tanımlayıcısına ihtiyaç duymasıdır . Hafıza kısıtlıysanız geri sarabilir, yazabilir, her yinelemede tamponu temizleyebilirsiniz. Veya bunun yerine gerçek bir geçici dosya kullanın.
complex857

@ complex857 csv için nasıl sütun başlığı ekleyebilirim?
user2302780

@ user2302780: Verilerinizin önüne bir sütun adı satırı ekliyorsunuz. Veri dizilerindeki anahtarları şu şekilde kullanabilirsiniz$data = array_merge(array(array_keys($data[0])), $data);
complex857

1
@JoseRojas bu beklenen bir şey çünkü telin üzerine bir şey koyduğunuzda (php ile şeyler çıkarmanın kavramsal olarak anlamı) buna geri dönemezsiniz. Kullanmak php://outputiçin ikinci güncellenmiş kod örneğine bakın.
complex857

18

@ Complex857 çözümüne yanıt vermek için yeterli itibarım yok. Harika çalışıyor, ama eklemek zorunda kaldım; Content-Disposition başlığının sonunda. Bu olmadan tarayıcı dosya adının sonuna iki tire ekler (örneğin "export.csv" yerine dosya "export.csv--" olarak kaydedilir). Muhtemelen başlık satırının sonunda \ r \ n temizlemeye çalışıyor.

Doğru çizgi şöyle görünmelidir:

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

CSV'nin içinde UTF-8 karakterleri olması durumunda, İçerik Türü satırını değiştirerek kodlamayı UTF-8 olarak değiştirmeniz gerekir:

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

Ayrıca, fseek () yerine rewind () kullanmayı daha zarif buluyorum:

rewind($f);

Çözümünüz için teşekkürler!


2
--Dosya adlarının sonlarını kendim hiç yaşamadım , ancak yanıtı güncelledim (neden sadece bir düzenleme göndermiyorum?)
complex857

14

Deneyin ... csv indir.

<?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();
?>

bir alan değeri içeriyorsa kırılır, bu yüzden
tsv'yi

14

Projem için kullandığım işlev bu ve beklendiği gibi çalışıyor.

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

1
Bunu wordpress send_headers kancasında uygulamaya çalışırken çok zorlandım, çünkü csv dosyasının sonuna geçerli tüm html sayfalarını her eklediğinde. Bu cevap beni çok engelliyor ama ben ara bellek işlemleri olmadan kullanıyorum.
Oleg Apanovich

temiz çıktı tamponu benim için bu kod satırlarının kullanılmadan önce oluşturulan dosyanın başında ve sonunda boş satırlar olması sorununu çözdü.
Sharunas Bielskis

8

Bir php dizisini CSV'ye dönüştürmek için aşağıdaki kodu kullanın

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

3

Dizi yapınız her zaman tam olarak bu şekilde çok boyutlu olacaksa, aşağıdaki gibi öğeleri yineleyebiliriz:

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

Bunu yapmanın bir yolu bu ... elle de yapabilirsiniz, ancak bu yol daha hızlı ve anlaşılması ve okunması daha kolaydır.

Ardından, karmaşık857'nin dosyayı tükürmek için yaptığı bir şeyi başlıklarınızı yönetirsiniz. Daha sonra artık ihtiyacınız yoksa unlink () kullanarak dosyayı silebilir veya isterseniz sunucuda bırakabilirsiniz.


-2

Aşağıdakileri kullanın,

echo "<script type='text/javascript'> window.location.href = '$file_name'; </script>";
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.