Mã PHP để chuyển đổi một truy vấn MySQL sang CSV [đã đóng]


128

Cách hiệu quả nhất để chuyển đổi truy vấn MySQL sang CSV trong PHP là gì?

Tốt nhất nên tránh các tệp tạm thời vì điều này làm giảm tính di động (đường dẫn thư mục và thiết lập quyền hệ thống tệp yêu cầu).

CSV cũng nên bao gồm một dòng tên trường hàng đầu.


73
Tại sao câu hỏi này được đóng lại là không mang tính xây dựng? Điều này là tốt và hoàn toàn rõ ràng.

14
@ Alec Bởi vì một số người điều hành ở đây là siêu nhân, bạn biết ... "Với siêu năng lực có trách nhiệm lớn!" - Chú Ben
độ chính xác của thuốc vào

18
@finitinessofinfinity quyền lực hỏng, quyền lực tuyệt đối hỏng hoàn toàn. Stackoverflow là một ví dụ tuyệt vời về điều đó.

16
Tôi đang bỏ phiếu để mở lại câu hỏi này!
TN888

9
Sáu tháng sau và tôi đang sử dụng câu trả lời cho điều này trong trang web của mình. Điều này có thể được mở lại?
Jon

Câu trả lời:


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

( tài liệu cho việc này ở đây: http://dev.mysql.com/doc/refman/5.0/en/select.html )

hoặc là:

$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
về mặt kỹ thuật, đây là phần tách biệt;)
John Douthat

5
Lưu ý việc sử dụng dấu gạch chéo về phía trước SELECT INTO OUTFILEngay cả trên Windows.
Johan

1
Hii điều này hoạt động tốt cho định dạng xls nhưng nếu tôi cố lưu dưới dạng tệp CSV, nó sẽ hiển thị tất cả các kết quả trong 1 cột. Tôi muốn lưu nó dưới dạng tệp csv.
vinod reddy

Trong số hai cái trên thì cái nào tốt hơn, an toàn hơn và tại sao?
Chella

1
Tôi có xu hướng đề xuất tùy chọn thứ hai an toàn hơn vì `CHỌN VÀO OUTFILE yêu cầu người dùng mysql có quyền truy cập vào hệ thống tệp để thay đổi các tệp có nguy cơ lớn.
Xe jeep

91

Kiểm tra câu hỏi / câu trả lời này . Nó ngắn gọn hơn @ Geoff và cũng sử dụng hàm fputcsv dựng sẵn.

$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
Bạn không có tiêu đề cột.
Paolo Bergantino

15
Trong trường hợp bất kỳ ai khác cũng ngu ngốc như tôi, đừng thay thế php://outputbằng tên tệp thực tế hoặc cố gắng đóng nó fcloseở cuối: đó không phải là tệp thực, chỉ là bí danh cho luồng đầu ra. Dù sao câu trả lời này đã làm việc hoàn hảo cho tôi, cảm ơn Jrgns!
J.Steve

@ J.Steve tôi niềm vui :)
Jrgns


1
mysql_num_fields () không hoạt động đối với tôi và các tiêu đề không được tạo. Là chức năng này không được chấp nhận hoặc một cái gì đó?
Doug

20

Nhìn vào tài liệu liên quan đến cú pháp CHỌN ... VÀO OUTFILE.

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

18

Một bản cập nhật cho @jrgns (với một số khác biệt cú pháp nhỏ).

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

Vì một số lý do, $ fp trả lại sai cho tôi.
Volatil3

Đối với MySQL hiện đại, bạn có thể sử dụng: $ headers [] = mysqli_fetch_field_direct ($ result, $ i) -> name;
Ben ở CA

Và thay đổi các hàm mysql_ khác thành các hàm mysqli_.
Ben ở CA

6

Nếu bạn muốn tải xuống được cung cấp dưới dạng tải xuống có thể được mở trực tiếp trong Excel, thì điều này có thể phù hợp với bạn: (được sao chép từ một dự án cũ chưa phát hành của tôi)

Các chức năng này thiết lập các tiêu đề:

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

Cái này sẽ gửi một CSV đến một luồng bằng kết quả mysql

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

Cái này sử dụng hàm trên để ghi CSV vào một tệp, được cung cấp bởi $ filename

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

Và đây là nơi phép màu xảy ra;)

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

Ví dụ:

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

1
Cảm ơn john mã rất hữu ích. Phải sửa đổi một dòng cho chức năng csvFromResult. thay vì while ($ row = mysql_fetch_row ($ result)) {fputcsv ($ stream, $ row); $ hàng ++; }, tôi đã phải sử dụng while ($ row = mysql_fetch_row ($ result)) {$ data [] = $ row; // fputcsv ($ stream, $ row); // $ hàng ++; } foreach ($ data dưới dạng $ d) {fputcsv ($ stream, $ d); }. cảm ơn một lần nữa cho một mã tuyệt vời như vậy.
mã hóabbq

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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.