Mảng PHP sang CSV


104

Tôi đang cố chuyển đổi một mảng sản phẩm thành tệp CSV, nhưng có vẻ như nó sẽ không như kế hoạch. Tệp CSV là một dòng dài, đây là mã của tôi:

for($i=0;$i<count($prods);$i++) {
$sql = "SELECT * FROM products WHERE id = '".$prods[$i]."'";
$result = $mysqli->query($sql);
$info = $result->fetch_array(); 
}

$header = '';

for($i=0;$i<count($info);$i++)  
  {
    $row = $info[$i];

    $line = '';
    for($b=0;$b<count($row);$b++)
    { 
    $value = $row[$b];                                      
        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");

array_to_CSV($data);


function array_to_CSV($data)
    {
        $outstream = fopen("php://output", 'r+');
        fputcsv($outstream, $data, ',', '"');
        rewind($outstream);
        $csv = fgets($outstream);
        fclose($outstream);
        return $csv;
    }

Ngoài ra, tiêu đề không buộc tải xuống. Tôi đã sao chép và dán đầu ra và lưu dưới dạng .csv

BIÊN TẬP

GIẢI QUYẾT VẤN ĐỀ:

Nếu bất kỳ ai khác đang tìm kiếm điều tương tự, hãy tìm một cách tốt hơn để làm điều đó:

$num = 0;
$sql = "SELECT id, name, description FROM products";
if($result = $mysqli->query($sql)) {
     while($p = $result->fetch_array()) {
         $prod[$num]['id']          = $p['id'];
         $prod[$num]['name']        = $p['name'];
         $prod[$num]['description'] = $p['description'];
         $num++;        
    }
 }
$output = fopen("php://output",'w') or die("Can't open php://output");
header("Content-Type:application/csv"); 
header("Content-Disposition:attachment;filename=pressurecsv.csv"); 
fputcsv($output, array('id','name','description'));
foreach($prod as $product) {
    fputcsv($output, $product);
}
fclose($output) or die("Can't close php://output");

Sử dụng $ info [] = $ result-> fetch_array (); nếu không nó sẽ có thông tin chi tiết về sản phẩm cuối cùng
GBD

@JohnnyFaldo: Cảm ơn anh bạn! Chỉ những gì tôi cần nó.
Cesar

Chào! Tôi biết đây là một câu hỏi cũ, nhưng bạn có thể trả lời câu hỏi của riêng mình. Nó có thể giúp mọi người tìm ra giải pháp cho một vấn đề tương tự.
Gustavo Straube,

có ai khác nhận được dòng đầu tiên và hai khối đầu tiên của dòng thứ hai trống không ??
mach2

Câu trả lời:


97

Thay vì viết ra các giá trị, hãy cân nhắc sử dụng fputcsv().

Điều này có thể giải quyết vấn đề của bạn ngay lập tức.


1
Tôi nên đề cập rằng điều này sẽ tạo một tệp trên máy chủ của bạn, vì vậy bạn sẽ cần đọc nội dung của tệp đó trước khi xuất ra, ngoài ra nếu bạn không muốn lưu một bản sao thì bạn sẽ cần phải ùn liên kết tệp khi Bạn xong việc rồi.
Martin Lyne

Cảm ơn bạn đã chỉnh sửa Vyktor, hôm nay tôi đánh máy rất tệ! Tôi thường rất cẩn thận.
Martin Lyne

tôi có thể chỉnh sửa mã tôi có ở trên để làm điều này không? như nó xuất ra tất cả các trường, và sử dụng ví dụ về fputcsv trong cuốn hướng dẫn tôi không thể có được nó để làm điều này
JohnnyFaldo

7
array_to_CSV ($ data); function array_to_CSV ($ data) {$ outstream = fopen ("php: // output", 'r +'); fputcsv ($ outstream, $ data, '', '"'); tua lại ($ outstream); $ csv = fgets ($ outstream); fclose ($ outstream); return $ csv;}
JohnnyFaldo

vâng mà giải quyết nó cảm ơn bạn, đã thêm các giải pháp trong câu hỏi ban đầu
JohnnyFaldo

16

Đây là một giải pháp đơn giản để xuất một mảng sang chuỗi csv:

function array2csv($data, $delimiter = ',', $enclosure = '"', $escape_char = "\\")
{
    $f = fopen('php://memory', 'r+');
    foreach ($data as $item) {
        fputcsv($f, $item, $delimiter, $enclosure, $escape_char);
    }
    rewind($f);
    return stream_get_contents($f);
}

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

5

Hãy thử sử dụng;

PHP_EOL

Để kết thúc mỗi dòng mới trong đầu ra CSV của bạn.

Tôi giả định rằng văn bản đang phân tách, nhưng không chuyển sang hàng tiếp theo?

Đó là một hằng số PHP. Nó sẽ xác định đúng đầu dòng bạn cần.

Ví dụ: Windows sử dụng "\ r \ n". Tôi đã vắt óc suy nghĩ với cái đó khi đầu ra của tôi không chuyển sang một dòng mới.

làm thế nào để viết dòng mới thống nhất trong PHP?


2

Tôi biết điều này đã cũ, tôi đã gặp trường hợp cần khóa mảng cũng được đưa vào CSV, vì vậy tôi đã cập nhật tập lệnh của Jesse Q để làm điều đó. Tôi đã sử dụng một chuỗi làm đầu ra, vì mã hóa không thể thêm dòng mới (dòng mới là thứ tôi đã thêm và thực sự phải ở đó).

Xin lưu ý, điều này chỉ hoạt động với các mảng giá trị đơn (key, value). nhưng có thể dễ dàng được cập nhật để xử lý đa chiều (key, array()).

function arrayToCsv( array &$fields, $delimiter = ',', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
    $delimiter_esc = preg_quote($delimiter, '/');
    $enclosure_esc = preg_quote($enclosure, '/');

    $output = '';
    foreach ( $fields as $key => $field ) {
        if ($field === null && $nullToMysqlNull) {
            $output = '';
            continue;
        }

        // Enclose fields containing $delimiter, $enclosure or whitespace
        if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
            $output .= $key;
            $output .= $delimiter;
            $output .= $enclosure . str_replace($enclosure, $enclosure . $enclosure,     $field) . $enclosure;
            $output .= PHP_EOL;
        }
        else {
            $output .= $key;
            $output .= $delimiter;
            $output .= $field;
            $output .= PHP_EOL;
        }
    }

    return  $output ;
}

1

Trong trường hợp của tôi, mảng của tôi là nhiều chiều, có khả năng với các mảng là giá trị. Vì vậy, tôi đã tạo hàm đệ quy này để phá vỡ hoàn toàn mảng:

function array2csv($array, &$title, &$data) {
    foreach($array as $key => $value) {      
        if(is_array($value)) {
            $title .= $key . ",";
            $data .= "" . ",";
            array2csv($value, $title, $data);
        } else {
            $title .= $key . ",";
            $data .= '"' . $value . '",';
        }
    }
}

Vì các cấp độ khác nhau của mảng của tôi không phù hợp với định dạng CSV phẳng, nên tôi đã tạo một cột trống với khóa của mảng phụ để dùng làm "phần giới thiệu" mô tả cho cấp dữ liệu tiếp theo. Đầu ra mẫu:

agentid     fname           lname      empid    totals  sales   leads   dish    dishnet top200_plus top120  latino  base_packages
G-adriana   ADRIANA EUGENIA PALOMO PAIZ 886                0    19              0         0         0         0      0

Bạn có thể dễ dàng xóa cột "giới thiệu" (mô tả) đó, nhưng trong trường hợp của tôi, tôi có các tiêu đề cột lặp lại, tức là inbound_leads, trong mỗi mảng con, vì vậy, điều đó đã cho tôi dấu ngắt / tiêu đề trước phần tiếp theo. Tẩy:

$title .= $key . ",";
$data .= "" . ",";

sau is_array () để thu gọn mã hơn nữa và loại bỏ cột thừa.

Vì tôi muốn cả hàng tiêu đề và hàng dữ liệu, tôi truyền hai biến vào hàm và sau khi hoàn thành lệnh gọi hàm, hãy kết thúc cả hai bằng PHP_EOL:

$title .= PHP_EOL;
$data .= PHP_EOL;

Vâng, tôi biết tôi bỏ thêm một dấu phẩy, nhưng để ngắn gọn, tôi không xử lý nó ở đây.


Đây có vẻ như là một câu trả lời cụ thể cho một câu hỏi rất chung chung và bạn thừa nhận đã để thừa dấu phẩy (do vấn đề thực sự của việc sử dụng chuỗi thay vì mảng) cũng như không trích dẫn dòng tiêu đề và có thêm một số lệnh gọi không cần thiết. Tôi đã định hình lại tất cả những điều này bên trong một câu trả lời cho một câu hỏi khác .
LWC

1

Mảng dữ liệu được chuyển đổi thành định dạng csv 'text / csv' bằng hàm php tích hợp sẵn fputcsv xử lý dấu phẩy, dấu ngoặc kép, v.v.
Xem tại
https://coderwall.com/p/zvzwwa/array-to-comma-separated -string-in-php http://www.php.net/manual/en/ Chức năng.fputcsv.php


Liên kết đến một giải pháp được hoan nghênh, nhưng hãy đảm bảo câu trả lời của bạn hữu ích nếu không có nó: thêm ngữ cảnh xung quanh liên kết để những người dùng đồng nghiệp của bạn sẽ biết nó là gì và tại sao nó ở đó, sau đó trích dẫn phần có liên quan nhất của trang bạn ' đang liên kết lại trong trường hợp trang đích không có sẵn. Các câu trả lời ít hơn một liên kết có thể bị xóa.
geisterfurz007

0

Nó đã làm việc cho tôi.

 $f=fopen('php://memory','w');
 $header=array("asdf ","asdf","asd","Calasdflee","Start Time","End Time" );      
 fputcsv($f,$header);
 fputcsv($f,$header);
 fputcsv($f,$header); 
 fseek($f,0);
 header('content-type:text/csv'); 
 header('Content-Disposition: attachment; filename="' . $filename . '";');
 fpassthru($f);```
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.