Xuất sang CSV qua PHP


Câu trả lời:


308

Cá nhân tôi sử dụng chức năng này để tạo nội dung CSV từ bất kỳ mảng nào.

function array2csv(array &$array)
{
   if (count($array) == 0) {
     return null;
   }
   ob_start();
   $df = fopen("php://output", 'w');
   fputcsv($df, array_keys(reset($array)));
   foreach ($array as $row) {
      fputcsv($df, $row);
   }
   fclose($df);
   return ob_get_clean();
}

Sau đó, bạn có thể khiến người dùng của mình tải xuống tệp đó bằng cách sử dụng:

function download_send_headers($filename) {
    // disable caching
    $now = gmdate("D, d M Y H:i:s");
    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
    header("Last-Modified: {$now} GMT");

    // force download  
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");

    // disposition / encoding on response body
    header("Content-Disposition: attachment;filename={$filename}");
    header("Content-Transfer-Encoding: binary");
}

Ví dụ sử dụng:

download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo array2csv($array);
die();

1
trên máy chủ cục bộ, nó hoạt động, nhưng ở một nơi xa, nó hiển thị một trang mới có nội dung và không có cửa sổ tải xuống (xin lỗi vì tiếng Anh của tôi)
khaled_webdev

2
Có thể có một số lý do cho lỗi, cách đơn giản nhất để tìm thấy chúng là xem tệp apache error.log của bạn.
Alain Tiemblo

7
Bạn cần phải thực hiện một die();cuộc gọi ngay sau đó echo array2csv();, sẽ chỉnh sửa câu trả lời của tôi. Hãy chắc chắn để tạo csv của bạn trước khi xuất một cái gì đó trong trang của bạn.
Alain Tiemblo

1
@ ring0 Tôi đoán đưa ngày qua trong phần đầu vô hiệu hóa bộ nhớ đệm trang, nhìn vào 2 ví dụ php.net/manual/en/function.header.php
Abhishek Madhani

2
Cung cấp các loại mime cho trình duyệt của bạn để bạn có được phương thức tải xuống thay vì csv được hiển thị trong cửa sổ hiện tại.
Alain Tiemblo

32

Bạn có thể xuất ngày bằng lệnh này.

<?php

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

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);
?>

Trước tiên, bạn phải tải dữ liệu từ máy chủ mysql vào một mảng


10
Hoặc, bạn có thể thực hiện fputcsv () bên trong một vòng lặp tìm nạp tiêu chuẩn và đưa nó xuống thẳng ra khỏi các kết quả được trả về.
DampeS8N

10
@ DampeS8N, +1 cho việc sử dụng "plop it down out" trong một câu.
Cá cơm

điều này được sao chép mà không có sự ghi nhận từ hướng dẫn PHP cho fputcsv
BenK

14

Chỉ cần cho hồ sơ, sự kết hợp là waaaaaay nhanh hơn (ý tôi là vậy) hơn fputcsvhoặc thậm chí implode; Và kích thước tệp nhỏ hơn:

// The data from Eternal Oblivion is an object, always
$values = (array) fetchDataFromEternalOblivion($userId, $limit = 1000);

// ----- fputcsv (slow)
// The code of @Alain Tiemblo is the best implementation
ob_start();
$csv = fopen("php://output", 'w');
fputcsv($csv, array_keys(reset($values)));
foreach ($values as $row) {
    fputcsv($csv, $row);
}
fclose($csv);
return ob_get_clean();

// ----- implode (slow, but file size is smaller)
$csv = implode(",", array_keys(reset($values))) . PHP_EOL;
foreach ($values as $row) {
    $csv .= '"' . implode('","', $row) . '"' . PHP_EOL;
}
return $csv;
// ----- concatenation (fast, file size is smaller)
// We can use one implode for the headers =D
$csv = implode(",", array_keys(reset($values))) . PHP_EOL;
$i = 1;
// This is less flexible, but we have more control over the formatting
foreach ($values as $row) {
    $csv .= '"' . $row['id'] . '",';
    $csv .= '"' . $row['name'] . '",';
    $csv .= '"' . date('d-m-Y', strtotime($row['date'])) . '",';
    $csv .= '"' . ($row['pet_name'] ?: '-' ) . '",';
    $csv .= PHP_EOL;
}
return $csv;

Đây là kết luận về việc tối ưu hóa một số báo cáo, từ mười đến hàng nghìn hàng. Ba ví dụ hoạt động tốt dưới 1000 hàng, nhưng không thành công khi dữ liệu lớn hơn.



8

Hoạt động với hơn 100 dòng, nếu bạn chỉ định kích thước của tệp trong tiêu đề, hãy gọi phương thức get () trong lớp của riêng bạn

function setHeader($filename, $filesize)
{
    // disable caching
    $now = gmdate("D, d M Y H:i:s");
    header("Expires: Tue, 01 Jan 2001 00:00:01 GMT");
    header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
    header("Last-Modified: {$now} GMT");

    // force download  
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    header('Content-Type: text/x-csv');

    // disposition / encoding on response body
    if (isset($filename) && strlen($filename) > 0)
        header("Content-Disposition: attachment;filename={$filename}");
    if (isset($filesize))
        header("Content-Length: ".$filesize);
    header("Content-Transfer-Encoding: binary");
    header("Connection: close");
}

function getSql()
{
    // return you own sql
    $sql = "SELECT id, date, params, value FROM sometable ORDER BY date;";
    return $sql;
}

function getExportData()
{
    $values = array();

    $sql = $this->getSql();
    if (strlen($sql) > 0)
    {
        $result = dbquery($sql); // opens the database and executes the sql ... make your own ;-) 
        $fromDb = mysql_fetch_assoc($result);
        if ($fromDb !== false)
        {
            while ($fromDb)
            {
                $values[] = $fromDb;
                $fromDb = mysql_fetch_assoc($result);
            }
        }
    }
    return $values;
}

function get()
{
    $values = $this->getExportData(); // values as array 
    $csv = tmpfile();

    $bFirstRowHeader = true;
    foreach ($values as $row) 
    {
        if ($bFirstRowHeader)
        {
            fputcsv($csv, array_keys($row));
            $bFirstRowHeader = false;
        }

        fputcsv($csv, array_values($row));
    }

    rewind($csv);

    $filename = "export_".date("Y-m-d").".csv";

    $fstat = fstat($csv);
    $this->setHeader($filename, $fstat['size']);

    fpassthru($csv);
    fclose($csv);
}


6

Giống như @ Dampes8N đã nói:

$result = mysql_query($sql,$conecction);
$fp = fopen('file.csv', 'w');
while($row = mysql_fetch_assoc($result)){
    fputcsv($fp, $row);
}
fclose($fp);

Hi vọng điêu nay co ich.

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.