PHP'de bir kullanıcı için CSV Dosyası oluşturma


220

MySQL veritabanında veri var. Kullanıcıya verilerini CSV dosyası olarak alması için bir URL gönderiyorum.

Ben bağlantı, MySQL sorgu, vb e-posta var kaplı.

Bağlantıyı tıkladıklarında MySQL'den kayıt içeren bir CVS indirmek için nasıl bir pop-up alabilirim?

Kaydı almak için tüm bilgilere sahibim. Sadece PHP'nin CSV dosyasını oluşturmasını ve .csv uzantılı bir dosyayı indirmelerini sağlamayı göremiyorum.

Yanıtlar:


280

Deneyin:

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "record1,record2,record3\n";
die;

vb

Düzenleme: İşte isteğe bağlı olarak CSV alanlarını kodlamak için kullandığım bir kod pasajı:

function maybeEncodeCSVField($string) {
    if(strpos($string, ',') !== false || strpos($string, '"') !== false || strpos($string, "\n") !== false) {
        $string = '"' . str_replace('"', '""', $string) . '"';
    }
    return $string;
}

11
CSV kurallarının önemli olduğunu unutmayın. İyi bir görüntü elde etmek için alanlarınızın etrafına çift tırnak işareti koyun ve alanların içindeki çift tırnak işaretlerini çift çift tırnak içine almayı unutmayın: `echo '"' .str_replace ('"', '" "', $ record1). '","'. str_replace ....
Mala

46
Açıklığa kavuşturmak gerekirse, CSV için doğru HTTP İçerik Türü başlığı application / csv değil, text / csv'dir. Herhangi bir modern tarayıcının her iki şekilde de ilgileneceğinden şüpheliyim, ancak standartlar olduğu için bunları da kullanabiliriz.
fentie

10
Genel olarak, CSV dosyaları oluştururken lütfen RFC 4180'i takip edin. tools.ietf.org/html/rfc4180
Oleg Barshay

5
@Oleg Barshay: OMG, bu RFC bir ana parça: "Alanları kuşatmak için çift tırnak işareti kullanılıyorsa, bir alanın içinde görünen çift tırnaktan önce başka bir çift tırnak işareti eklenerek kaçılmalıdır.". BAŞKA BİR ÇİFT-TEKLİF!
aefxx

465
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");

function outputCSV($data) {
  $output = fopen("php://output", "wb");
  foreach ($data as $row)
    fputcsv($output, $row); // here you can change delimiter/enclosure
  fclose($output);
}

outputCSV(array(
  array("name 1", "age 1", "city 1"),
  array("name 2", "age 2", "city 2"),
  array("name 3", "age 3", "city 3")
));

php: // çıktı
fputcsv


64
Daha fazla insanın bunu görmesi ve oy vermesi gerekiyor. Bu, bu sayfadaki en iyi cevaptır. PHP zaten CSV içeriğini biçimlendirmek için yerleşik işlevlere sahiptir. Herkes onları kullanmalı. Great answer, @Andrey :)
maček

2
Çok kötü fputcsv () yine de düzgün çalışmıyor :( bugs.php.net/bug.php?id=50686
gou1

4
Güzel, ama outputCSVişlev gereksiz derecede karmaşık. Değerlerini doğrudan içine göndererek biraz foreachdaha $arraybitirebilirsiniz fputcsv. Buna gerek yok __outputCSVve array_walk:)foreach($data as $vals) {fputcsv($filehandler,$vals);}
Sygmoral

Sonunda Excel'de açık olması için .csv'ye ihtiyaç duyduğum için dizideki Fransızca karakterlerle ilgili bazı sorunlar yaşıyorum. Aksanlı karakterleri boğar. "Prévalence","age 1","city 1" Herhangi bir fikir gibi şeyler ? UTF-8 ile uğraşmak şu ana kadar yardımcı olmadı.
Voodoo

1
@theosem Sınırlayıcı, işletim sistemi veya Excel dışa aktarma ayarlarına bağlıdır. Sınırlayıcı hakkında not ekledim.
Andrii Nemchenko

19

İşte @Andrew tarafından yayınlanan php.net fonksiyonunun geliştirilmiş bir versiyonudur.

function download_csv_results($results, $name = NULL)
{
    if( ! $name)
    {
        $name = md5(uniqid() . microtime(TRUE) . mt_rand()). '.csv';
    }

    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename='. $name);
    header('Pragma: no-cache');
    header("Expires: 0");

    $outstream = fopen("php://output", "wb");

    foreach($results as $result)
    {
        fputcsv($outstream, $result);
    }

    fclose($outstream);
}

Kullanımı gerçekten çok kolay ve MySQL (i) / PDO sonuç kümeleriyle harika çalışıyor.

download_csv_results($results, 'your_name_here.csv');

exit()Sayfa ile işiniz bittiğinde bunu aramayı unutmayın .


Ayırıcıyı olarak nasıl değiştirirsiniz; ?
Huysuz

1
bu olayı tetiklemek için nasıl bir düğme eklemeliyiz, böylece kullanıcı talep üzerine CSV dosyasını indirebilir?
CanCeylan

"Fopen (" php: // output "," w ");" Bunu "$ fp = fopen ('stats.csv', 'w') olarak değiştirdiğimde" hata göstermez. Ama sonra elbette işe yaramıyor. Nasıl çözmeliyim?
CanCeylan

@CanCeylan, Bu kendi başına bir soru ve bunu çözmek için daha fazla ayrıntıya ihtiyacım var.
Xeoncross

1
Ekle fputcsv($outstream, array_keys($results[0]));senin hemen önce foreachsütun başlıkları da dahil etmek.
Justin

16

Daha önce söylenenlerin hepsine ek olarak şunları eklemeniz gerekebilir:

header("Content-Transfer-Encoding: UTF-8");

İnsanların adları veya şehirleri gibi içinde birden fazla dil bulunan dosyaları kullanırken çok kullanışlıdır.


9

Konu biraz eski, biliyorum, ama gelecekteki referans ve kendim gibi noobs için:

Buradaki herkes CSV'nin nasıl oluşturulacağını açıklıyor, ancak sorunun temel bir bölümünü kaçırıyor: nasıl bağlantı kurulur. CSV dosyasının indirilmesine bağlanmak için, sadece .php dosyasına bağlanırsınız, bu da .csv dosyası olarak yanıt verir. PHP üstbilgileri bunu yapar. Bu, sorgu dizesine değişkenler eklemek ve çıktıyı özelleştirmek gibi harika şeyler sağlar:

<a href="my_csv_creator.php?user=23&amp;othervariable=true">Get CSV</a>

my_csv_creator.php, sorgu dizesinde verilen değişkenlerle çalışabilir ve örneğin farklı veya özelleştirilmiş veritabanı sorguları kullanabilir, CSV sütunlarını değiştirebilir, dosya adını kişiselleştirebilir vb.

User_John_Doe_10_Dec_11.csv

1
Uh - bunu okuyan herkes bu yaklaşıma çok ihtiyatlı davranır. Girişlerin düzgün bir şekilde kaçmadığından emin olabilirsiniz ve bu da uygulamanızda büyük güvenlik deliklerine yol açabilir.
calumbrodie

Yöntemi çok güvenli ve harika çalışıyor. Oturumla erişimi kolayca kontrol edebilir ve ayrıca bir oturumda csv'ye koymak istediğiniz tüm bilgileri saklayabilirsiniz. Sonra sadece bir csv dönüştürme sürecinin bir parçası olarak unset. Ben sadece bir sorgu dizesi yerine oturum vars kullanmanızı öneririz.
inorganik

1
Bu yöntemde güvenlik açığı yoktur. Başvuruda bulunulan php dosyası sanitasyon ve erişim kontrolü işi yapıyorsa. Ama bunların hepsini burada göstermek gerçekten mantıklı değil. Gönderinin amacı, url'nin csv'yi oluşturduğu her şeye bağlantı verebilmenizdir.
danielson317

8

Dosyanızı oluşturun ve Farklı Kaydet'i tetiklemek için doğru başlıkla bir referans döndürün - aşağıdakileri gerektiği gibi düzenleyin. CSV verilerinizi $ csvdata'ya ekleyin.

$fname = 'myCSV.csv';
$fp = fopen($fname,'wb');
fwrite($fp,$csvdata);
fclose($fp);

header('Content-type: application/csv');
header("Content-Disposition: inline; filename=".$fname);
readfile($fname);

1
"Satır içi" İçerik Kullanımı , tarayıcının indirmeden göstermeye çalışması gerektiği anlamına gelir (IE bunun için bir Excel örneği yerleştirme eğilimindedir). Bir indirme işlemini zorlamak için gerekli olan "ek" tir.
Gert van den Berg

5

İşte PDO kullanarak ve sütun başlıklarını içeren tam çalışan bir örnek:

$query = $pdo->prepare('SELECT * FROM test WHERE id=?');
$query->execute(array($id));    
$results = $query->fetchAll(PDO::FETCH_ASSOC);
download_csv_results($results, 'test.csv'); 
exit();


function download_csv_results($results, $name)
{            
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename='. $name);
    header('Pragma: no-cache');
    header("Expires: 0");

    $outstream = fopen("php://output", "wb");    
    fputcsv($outstream, array_keys($results[0]));

    foreach($results as $result)
    {
        fputcsv($outstream, $result);
    }

    fclose($outstream);
}

4

Önce verileri ayırıcı olarak virgülle bir String olarak ("," ile ayrılmış) yapın. Böyle bir şey

$CSV_string="No,Date,Email,Sender Name,Sender Email \n"; //making string, So "\n" is used for newLine

$rand = rand(1,50); //Make a random int number between 1 to 50.
$file ="export/export".$rand.".csv"; //For avoiding cache in the client and on the server 
                                     //side it is recommended that the file name be different.

file_put_contents($file,$CSV_string);

/* Or try this code if $CSV_string is an array
    fh =fopen($file, 'w');
    fputcsv($fh , $CSV_string , ","  , "\n" ); // "," is delimiter // "\n" is new line.
    fclose($fh);
*/

3

Hey Çok iyi çalışıyor .... !!!! Teşekkürler Peter Mortensen ve Connor Burton

<?php
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

ini_set('display_errors',1);
$private=1;
error_reporting(E_ALL ^ E_NOTICE);

mysql_connect("localhost", "user", "pass") or die(mysql_error());
mysql_select_db("db") or die(mysql_error());

$start = $_GET["start"];
$end = $_GET["end"];

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error());

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    $result.="{$row['email']},";
    $result.="\n";
    echo $result;
}

?>


Do DEĞİL üretimde bu kodu kullanın, bu SQL enjeksiyon karşı savunmasızdır
ntzm

2

Basit yöntem -

$data = array (
    'aaa,bbb,ccc,dddd',
    '123,456,789',
    '"aaa","bbb"');

$fp = fopen('data.csv', 'wb');
foreach($data as $line){
    $val = explode(",",$line);
    fputcsv($fp, $val);
}
fclose($fp);

Böylece $datadizinin her satırı yeni oluşturulan CSV dosyanızın yeni bir satırına gider. Yalnızca PHP 5 ve üstü için çalışır.


2

Fputcsv işlevini kullanarak verilerinizi CSV'ye yazabilirsiniz . aşağıdaki örneğe bakalım. Liste dizisini CSV dosyasına yazın

$list[] = array("Cars", "Planes", "Ships");
$list[] = array("Car's2", "Planes2", "Ships2");
//define headers for CSV 
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file_name.csv');
//write data into CSV
$fp = fopen('php://output', 'wb');
//convert data to UTF-8 
fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($list as $line) {
    fputcsv($fp, $line);
}
fclose($fp);

1

En kolay yol, bunun gibi özel bir CSV sınıfı kullanmaktır :

$csv = new csv();
$csv->load_data(array(
    array('name'=>'John', 'age'=>35),
    array('name'=>'Adrian', 'age'=>23), 
    array('name'=>'William', 'age'=>57) 
));
$csv->send_file('age.csv'); 

1

Onun yerine:

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    $result.="{$row['email']},";
    $result.="\n";
    echo $result;
}

kullanın:

$query = "SELECT * FROM customers WHERE created>='{$start} 00:00:00'  AND created<='{$end} 23:59:59'   ORDER BY id";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    echo implode(",", $row)."\n";
}

1

Zaten çok iyi bir çözüm geldi. Ben sadece bir newbie toplam yardım almak için toplam kodu koyuyorum

<?php
extract($_GET); //you can send some parameter by query variable. I have sent table name in *table* variable

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=$table.csv");
header("Pragma: no-cache");
header("Expires: 0");

require_once("includes/functions.php"); //necessary mysql connection functions here

//first of all I'll get the column name to put title of csv file.
$query = "SHOW columns FROM $table";
$headers = mysql_query($query) or die(mysql_error());
$csv_head = array();
while ($row = mysql_fetch_array($headers, MYSQL_ASSOC))
{
    $csv_head[] =  $row['Field'];
}
echo implode(",", $csv_head)."\n";

//now I'll bring the data.
$query = "SELECT * FROM $table";
$select_c = mysql_query($query) or die(mysql_error()); 

while ($row = mysql_fetch_array($select_c, MYSQL_ASSOC))
{
    foreach ($row as $key => $value) {
            //there may be separator (here I have used comma) inside data. So need to put double quote around such data.
        if(strpos($value, ',') !== false || strpos($value, '"') !== false || strpos($value, "\n") !== false) {
            $row[$key] = '"' . str_replace('"', '""', $value) . '"';
        }
    }
    echo implode(",", $row)."\n";
}

?>

Bu kodu csv-download.php dosyasına kaydettim

Şimdi bu verileri csv dosyasını indirmek için nasıl kullandığımı görün

<a href="csv-download.php?table=tbl_vfm"><img title="Download as Excel" src="images/Excel-logo.gif" alt="Download as Excel" /><a/>

Bağlantıyı tıkladığımda, beni tarayıcıdaki csv-download.php sayfasına götürmeden dosyayı indirdim.


0

CSV olarak göndermesini ve dosya adını vermesini sağlamak için header () öğesini kullanın:

http://us2.php.net/header

header('Content-type: text/csv');
header('Content-disposition: attachment; filename="myfile.csv"');

CSV'nin kendisini oluştururken, sonuç kümesinde dolaşırsınız, çıktıyı biçimlendirir ve gönderirsiniz, tıpkı diğer tüm içeriklerde olduğu gibi.


0

Kendi CSV kodunuzu yazmak muhtemelen zaman kaybıdır, sadece lig / csv gibi bir paket kullanın - sizin için tüm zor şeylerle ilgilenir, belgeler iyidir ve çok kararlı / güvenilirdir:

http://csv.thephpleague.com/

Besteci kullanmanız gerekir. Bestecinin ne olduğunu bilmiyorsanız, bir göz atmanızı şiddetle tavsiye ederim: https://getcomposer.org/


0
<?
    // Connect to database
    $result = mysql_query("select id
    from tablename
    where shid=3");
    list($DBshid) = mysql_fetch_row($result);

    /***********************************
    Write date to CSV file
    ***********************************/

    $_file = 'show.csv';
    $_fp = @fopen( $_file, 'wb' );

    $result = mysql_query("select name,compname,job_title,email_add,phone,url from UserTables where id=3");

    while (list( $Username, $Useremail_add, $Userphone, $Userurl) = mysql_fetch_row($result))
    {
        $_csv_data = $Username.','.$Useremail_add.','.$Userphone.','.$Userurl . "\n";
        @fwrite( $_fp, $_csv_data);
    }
    @fclose( $_fp );
?>

0

PHP betiği kullanarak CSV dosyasına nasıl yazılır? Aslında ben de bunu arıyordum. PHP ile kolay bir iştir. fputs (işleyici, içerik) - bu işlev benim için verimli çalışır. İlk önce fopen ($ CSVFileName, 'wb') kullanarak içerik yazmanız gereken dosyayı açmanız gerekir.

$CSVFileName = test.csv”;
$fp = fopen($CSVFileName, wb’);

//Multiple iterations to append the data using function fputs()
foreach ($csv_post as $temp)
{
    $line = “”;
    $line .= Content 1 . $comma . $temp . $comma . Content 2 . $comma . 16/10/2012″.$comma;
    $line .= \n”;
    fputs($fp, $line);
}

Bağlantılar zaman içinde değişme veya kaybolma eğilimi gösterdiğinden, bağlantıyı bağlamak yerine kendisine kod eklemek her zaman tercih edilir.
Sgoettschkes

Cevabınız çok eski bir konu. 2008 yılında, virgülle ayrılmış satırlarınızı oluşturmak standart bir uygulama olsa da, PHP 5.1.0'dan beri doğru yöntem yerleşik fputcsv işlevini ( php.net/fputcsv ) kullanmak olacaktır. Eski konuları okurken, içerdikleri bilgilerin hala alakalı olduğundan emin olun.
Luke Mills

-1

$outputCSV verilerini değişkene koyun ve doğru başlıklarla yankılayın

header("Content-type: application/download\r\n");
header("Content-disposition: filename=filename.csv\r\n\r\n");
header("Content-Transfer-Encoding: ASCII\r\n");
header("Content-length: ".strlen($output)."\r\n");
echo $output;
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.