MySQL sorgusunu CSV'ye dönüştürmek için PHP kodu [kapalı]


128

PHP'de bir MySQL sorgusunu CSV'ye dönüştürmenin en etkili yolu nedir lütfen?

Taşınabilirliği azalttığından (dizin yolları ve dosya sistemi izinlerinin ayarlanması gerekir) geçici dosyalardan kaçınmak en iyisidir.

CSV ayrıca bir üst satır alan adı içermelidir.


74
Bu soru neden yapıcı olmadığı için kapatıldı? Bu güzel ve gayet açık.

14
@Alec Buradaki bazı moderatörler süper moderatör olduğu için, bilirsiniz ... "Süper güçler büyük sorumluluk getirir!" - Ben Amca
finitenessofinfinity

18
@finitenessofinfinity gücü bozar, mutlak güç kesinlikle bozar. Stackoverflow, bunun mükemmel bir örneğidir.

16
Bu soruyu yeniden açmak için oy kullanıyorum!
TN888

9
Altı ay sonra ve bunun yanıtlarını web sitemde kullanıyorum. Bu yeniden açılabilir mi?
Jon

Yanıtlar:


138
SELECT * INTO OUTFILE "c:/mydata.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM my_table;

( bunun için belgeler şurada: http://dev.mysql.com/doc/refman/5.0/en/select.html )

veya:

$select = "SELECT * FROM table_name";

$export = mysql_query ( $select ) or die ( "Sql error : " . mysql_error( ) );

$fields = mysql_num_fields ( $export );

for ( $i = 0; $i < $fields; $i++ )
{
    $header .= mysql_field_name( $export , $i ) . "\t";
}

while( $row = mysql_fetch_row( $export ) )
{
    $line = '';
    foreach( $row as $value )
    {                                            
        if ( ( !isset( $value ) ) || ( $value == "" ) )
        {
            $value = "\t";
        }
        else
        {
            $value = str_replace( '"' , '""' , $value );
            $value = '"' . $value . '"' . "\t";
        }
        $line .= $value;
    }
    $data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );

if ( $data == "" )
{
    $data = "\n(0) Records Found!\n";                        
}

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";

5
teknik olarak, bu sekmeyle ayrılmış;)
John Douthat

5
SELECT INTO OUTFILEWindows'ta bile eğik çizgi kullanımına dikkat edin .
Johan

1
Hii bu xls formatı için iyi çalışıyor ancak CSV dosyası olarak kaydetmeye çalışırsam tüm sonuçları 1 sütunda gösteriyor. Bunu csv dosyası olarak kaydetmek istiyorum.
vinod reddy

Yukarıdakilerden hangisi daha iyi, daha güvenli ve neden?
Chella

1
İkinci seçeneğin daha güvenli olduğunu önermek eğilimindeyim çünkü `` OUTFILE'ı SEÇ ', mysql kullanıcısının dosyaları değiştirmek için dosya sistemine erişmesini gerektiriyor, bu da potansiyel olarak büyük bir risk.
Jeepstone

91

Bu soruya / cevaba göz atın . @ Geoff'inkinden daha özlüdür ve ayrıca yerleşik fputcsv işlevini kullanır.

$result = $db_con->query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++) {
    $headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result) {
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="export.csv"');
    header('Pragma: no-cache');
    header('Expires: 0');
    fputcsv($fp, $headers);
    while ($row = $result->fetch_array(MYSQLI_NUM)) {
        fputcsv($fp, array_values($row));
    }
    die;
}

1
Sizinki sütun başlıklarına sahip değil.
Paolo Bergantino

15
Başkasının da benim kadar aptal olması durumunda, gerçek bir dosya adıyla değiştirmeyin php://outputveya fclosesonunda bir ile kapatmaya çalışmayın : bu gerçek bir dosya değil, sadece çıktı akışı için bir takma addır. Her neyse, bu cevap benim için mükemmel çalıştı, teşekkürler Jrgns!
J.Steve

@ J.Steve Benim zevkim :)
Jrgns


1
mysql_num_fields () benim için çalışmıyor ve başlıklar oluşturulmuyor. Bu işlev kullanımdan kaldırılmış veya başka bir şey mi?
Doug

20

SELECT ... INTO OUTFILE sözdizimi ile ilgili belgelere bakın .

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

18

@Jrgns için bir güncelleme (bazı küçük sözdizimi farklılıklarıyla) çözümü.

$result = mysql_query('SELECT * FROM `some_table`'); 
if (!$result) die('Couldn\'t fetch records'); 
$num_fields = mysql_num_fields($result); 
$headers = array(); 
for ($i = 0; $i < $num_fields; $i++) 
{     
       $headers[] = mysql_field_name($result , $i); 
} 
$fp = fopen('php://output', 'w'); 
if ($fp && $result) 
{     
       header('Content-Type: text/csv');
       header('Content-Disposition: attachment; filename="export.csv"');
       header('Pragma: no-cache');    
       header('Expires: 0');
       fputcsv($fp, $headers); 
       while ($row = mysql_fetch_row($result)) 
       {
          fputcsv($fp, array_values($row)); 
       }
die; 
} 

Nedense $ fp bana yanlış döndürüyor.
Volatil3

Modern MySQL için şunları kullanabilirsiniz: $ headers [] = mysqli_fetch_field_direct ($ sonuç, $ i) -> isim;
Ben CA'da

Ve diğer mysql_ işlevlerini mysqli_ işlevlerine değiştirin.
Ben CA'da

6

İndirmenin doğrudan Excel'de açılabilen bir indirme olarak sunulmasını istiyorsanız, bu sizin için işe yarayabilir: (eski, yayınlanmamış bir projemden kopyalanmış)

Bu işlevler başlıkları ayarlar:

function setExcelContentType() {
    if(headers_sent())
        return false;

    header('Content-type: application/vnd.ms-excel');
    return true;
}

function setDownloadAsHeader($filename) {
    if(headers_sent())
        return false;

    header('Content-disposition: attachment; filename=' . $filename);
    return true;
}

Bu, mysql sonucunu kullanarak bir akışa bir CSV gönderir

function csvFromResult($stream, $result, $showColumnHeaders = true) {
    if($showColumnHeaders) {
        $columnHeaders = array();
        $nfields = mysql_num_fields($result);
        for($i = 0; $i < $nfields; $i++) {
            $field = mysql_fetch_field($result, $i);
            $columnHeaders[] = $field->name;
        }
        fputcsv($stream, $columnHeaders);
    }

    $nrows = 0;
    while($row = mysql_fetch_row($result)) {
        fputcsv($stream, $row);
        $nrows++;
    }

    return $nrows;
}

Bu, $ filename ile verilen bir dosyaya bir CSV yazmak için yukarıdaki işlevi kullanır

function csvFileFromResult($filename, $result, $showColumnHeaders = true) {
    $fp = fopen($filename, 'w');
    $rc = csvFromResult($fp, $result, $showColumnHeaders);
    fclose($fp);
    return $rc;
}

Ve sihrin gerçekleştiği yer burası;)

function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
    setExcelContentType();
    setDownloadAsHeader($asFilename);
    return csvFileFromResult('php://output', $result, $showColumnHeaders);
}

Örneğin:

$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);

1
Teşekkürler john çok kullanışlı kod. CsvFromResult işlevi için bir satırı değiştirmek gerekiyordu. while ($ satır = mysql_fetch_row ($ sonuç)) {fputcsv ($ akım, $ satır) yerine; $ satır ++; }, while ($ satır = mysql_fetch_row ($ sonuç)) {$ data [] = $ satır; // fputcsv ($ akım, $ satır); // $ satırlar ++; } foreach ($ d olarak $ veri) {fputcsv ($ akım, $ d); }. Böyle harika bir kod için tekrar teşekkürler.
codingbbq

3
// Export to CSV
if($_GET['action'] == 'export') {

  $rsSearchResults = mysql_query($sql, $db) or die(mysql_error());

  $out = '';
  $fields = mysql_list_fields('database','table',$db);
  $columns = mysql_num_fields($fields);

  // Put the name of all fields
  for ($i = 0; $i < $columns; $i++) {
    $l=mysql_field_name($fields, $i);
    $out .= '"'.$l.'",';
  }
  $out .="\n";

  // Add all values in the table
  while ($l = mysql_fetch_array($rsSearchResults)) {
    for ($i = 0; $i < $columns; $i++) {
      $out .='"'.$l["$i"].'",';
    }
    $out .="\n";
  }
  // Output to browser with appropriate mime type, you choose ;)
  header("Content-type: text/x-csv");
  //header("Content-type: text/csv");
  //header("Content-type: application/csv");
  header("Content-Disposition: attachment; filename=search_results.csv");
  echo $out;
  exit;
}
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.