PHP 배열을 CSV로


104

제품 배열을 CSV 파일로 변환하려고하는데 계획이 없을 것 같습니다. CSV 파일은 한 줄로되어 있으며 다음은 내 코드입니다.

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

또한 헤더는 다운로드를 강요하지 않습니다. 출력을 복사하여 붙여넣고 .csv로 저장했습니다.

편집하다

해결 된 문제 :

다른 사람이 같은 것을 찾고 있다면 더 나은 방법을 찾았습니다.

$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");

$ info [] = $ result-> fetch_array (); 사용 그렇지 않으면 마지막 제품 세부 정보가 있습니다
GBD

@JohnnyFaldo : 감사합니다! 내가 필요한 것만.
Cesar

야! 나는 이것이 오래된 질문이라는 것을 알고 있지만 자신의 질문에 답할 수 있습니다. 유사한 문제에 대한 해결책을 찾는 데 도움이 될 수 있습니다.
Gustavo Straube 2018 년

다른 사람이 첫 번째 줄과 두 번째 줄의 처음 두 블록을 비우고 있습니까 ??
mach2

답변:


97

값을 쓰는 대신 fputcsv().

이렇게하면 문제가 즉시 해결 될 수 있습니다.


1
이것은 서버에 파일을 만들 것이므로 출력하기 전에 해당 파일의 내용을 읽어야합니다. 또한 사본을 저장하지 않으려는 경우 파일을 링크해야합니다. 당신은 끝났습니다.
Martin Lyne

편집 Vyktor에 감사드립니다. 오늘 제 타이핑이 끔찍합니다! 나는 보통 너무 조심 스럽습니다.
Martin Lyne 2012 년

이 작업을 수행하기 위해 위에있는 코드를 편집 할 수 있습니까? 모든 필드를 출력하고 매뉴얼에있는 fputcsv 예제를 사용하기
때문에이

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

예, 감사합니다. 원래 질문에 해결책을 추가했습니다
JohnnyFaldo

16

이것은 배열을 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

사용해보십시오;

PHP_EOL

CSV 출력에서 ​​각 새 줄을 종료합니다.

텍스트가 구분되어 있다고 가정하지만 다음 행으로 이동하지 않습니까?

그것은 PHP 상수입니다. 필요한 올바른 줄 끝을 결정합니다.

예를 들어 Windows는 "\ r \ n"을 사용합니다. 내 출력이 새로운 라인으로 깨지지 않았을 때 나는 그것으로 내 두뇌를 괴롭혔다.

PHP에서 통일 된 새 줄을 작성하는 방법?


2

나는 이것이 오래되었다는 것을 알고 있으며, CSV에도 배열 키를 포함 해야하는 경우가 있었으므로 Jesse Q의 스크립트를 업데이트하여 그렇게했습니다. implode는 새 줄을 추가 할 수 없기 때문에 문자열을 출력으로 사용했습니다 (새 줄은 내가 추가 한 것이므로 실제로 있어야 함).

이것은 단일 값 배열에서만 작동합니다 (key, value). 하지만 쉽게 다차원 (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

제 경우에는 배열이 다차원 적이 었으며 잠재적으로 배열을 값으로 사용했습니다. 그래서이 재귀 함수를 만들어 배열을 완전히 날려 버렸습니다.

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 . '",';
        }
    }
}

다양한 수준의 배열이 플랫 CSV 형식에 적합하지 않았기 때문에 다음 수준의 데이터에 대한 설명적인 "소개"역할을하기 위해 하위 배열의 키가있는 빈 열을 만들었습니다. 샘플 출력 :

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

"intro"(설명) 열을 쉽게 제거 할 수 있지만, 제 경우에는 각 하위 배열에 반복되는 열 헤더 (예 : inbound_leads)가있어서 다음 섹션 이전에 중단 / 제목을 제공했습니다. 없애다:

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

is_array () 뒤에 코드를 더 압축하고 추가 열을 제거합니다.

제목 행과 데이터 행을 모두 원했기 때문에 두 변수를 함수에 전달하고 함수 호출이 완료되면 둘 다 PHP_EOL로 종료합니다.

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

예, 쉼표를 추가로 남기는 것을 알고 있지만 간결성을 위해 여기에서는 처리하지 않았습니다.


이것은 매우 일반적인 질문에 대한 구체적인 대답처럼 보이며 (배열 대신 문자열을 사용하는 실제 문제로 인해) 추가 쉼표를 남겼으며 헤더 줄을 인용하지 않았고 불필요한 추가 호출이있었습니다. 나는이 모든 것을 다른 질문에 대한 답으로 재구성 했다 .
LWC

1

데이터 배열은 내장 된 PHP 함수에 의해 csv 'text / csv'형식으로 변환됩니다. fputcsv는 쉼표, 따옴표 등을 처리합니다. https://coderwall.com/p/zvzwwa/array-to-comma-separated를
보십시오.
-string-in-php
http://www.php.net/manual/en/function.fputcsv.php


솔루션에 대한 링크는 환영하지만 답변이없는 경우 유용한 지 확인하십시오 . 링크 주변에 컨텍스트를 추가 하여 동료 사용자가 그것이 무엇인지, 왜 존재하는지 알 수 있도록 한 다음 페이지에서 가장 관련성이 높은 부분을 인용하십시오. 대상 페이지를 사용할 수없는 경우 다시 연결합니다. 링크에 불과한 답변은 삭제 될 수 있습니다.
geisterfurz007

0

그것은 나를 위해 일했습니다.

 $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);```
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.