PHP 스크립트에서 CSV 파일을 만들고 다운로드하는 방법은 무엇입니까?


90

저는 초보 프로그래머이고 제 질문에 대해 많이 검색했지만 이에 대한 유용한 솔루션이나 자습서를 찾을 수 없습니다.

내 목표는 PHP 배열이 있고 배열 요소가 페이지의 목록에 표시되는 것입니다.

사용자가 원할 경우 배열 요소가있는 CSV 파일을 만들어 다운로드 할 수 있도록 옵션을 추가하고 싶습니다.

나는 이것을하는 방법을 모른다. 나도 많이 검색했습니다. 그러나 아직 유용한 리소스를 찾지 못했습니다.

직접 구현할 수 있도록 튜토리얼이나 솔루션 또는 조언을 제공하십시오. 저는 초보자이므로 구현하기 쉬운 솔루션을 제공하십시오.

내 배열은 다음과 같습니다.

Array
(
    [0] => Array
        (
            [fs_id] => 4c524d8abfc6ef3b201f489c
            [name] => restaurant
            [lat] => 40.702692
            [lng] => -74.012869
            [address] => new york
            [postalCode] => 
            [city] => NEW YORK
            [state] => ny
            [business_type] => BBQ Joint
            [url] => 
        )

)

2
CSV 파일에 대한 phpExcel은 .. 조금 너무 많이이다 php.net/manual/en/function.fputcsv.php
데미안 Pirsy

배열 구조를 보여주고 난은 CSV로 요소를 설정하는 몇 가지 코드 제공 c는
반 - 빠른

@ half-fast 나는 포스트에 배열 구조를 추가했습니다
user2302780

2
csv 파일에 열 제목을 어떻게 추가 할 수 있습니까?
user2302780 apr

답변:


204

내장 된 것을 사용할 수 있습니다. 배열에 fputcsv () 를 사용하여 배열에서 올바른 csv 행을 생성 할 수 있으므로 다음과 같이 반복해서 행을 수집해야합니다.

$f = fopen("tmp.csv", "w");
foreach ($array as $line) {
    fputcsv($f, $line);
}

브라우저에서 "다른 이름으로 저장"대화 상자를 제공하려면 다음과 같은 HTTP 헤더를 보내야합니다 (이 헤더에 대한 자세한 내용은 rfc ).

header('Content-Disposition: attachment; filename="filename.csv";');

함께 모아서:

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
    // open raw memory as file so no temp files needed, you might run out of memory though
    $f = fopen('php://memory', 'w'); 
    // loop over the input array
    foreach ($array as $line) { 
        // generate csv lines from the inner arrays
        fputcsv($f, $line, $delimiter); 
    }
    // reset the file pointer to the start of the file
    fseek($f, 0);
    // tell the browser it's going to be a csv file
    header('Content-Type: application/csv');
    // tell the browser we want to save it instead of displaying it
    header('Content-Disposition: attachment; filename="'.$filename.'";');
    // make php send the generated csv lines to the browser
    fpassthru($f);
}

다음과 같이 사용할 수 있습니다.

array_to_csv_download(array(
  array(1,2,3,4), // this array is going to be the first row
  array(1,2,3,4)), // this array is going to be the second row
  "numbers.csv"
);

업데이트 :
(가) 대신에 php://memory당신은 또한 사용할 수 있습니다 php://output파일 기술자에 대한과 추구 및 페지 :

function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
    header('Content-Type: application/csv');
    header('Content-Disposition: attachment; filename="'.$filename.'";');

    // open the "output" stream
    // see http://www.php.net/manual/en/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq
    $f = fopen('php://output', 'w');

    foreach ($array as $line) {
        fputcsv($f, $line, $delimiter);
    }
}   

2
echo생성 된 CSV 라인이 루프에 직접 포함 되지 않는 이유 는 무엇입니까?
Alex Shesterov 2013

1
@AlexShesterov, 주된 이유는 fputcsv()생성 된 줄을 반환하지 않기 때문에 쓸 파일 설명자가 필요하기 때문입니다. 메모리가 제한된 경우에도 반복 할 때마다 버퍼를 되 감고, 쓰고, 지울 수 있습니다. 또는 대신 실제 임시 파일을 사용하십시오.
complex857 2013-04-27

@ complex857 csv의 열 제목을 어떻게 추가 할 수 있습니까?
user2302780 2013-04-28

@ user2302780 : 데이터에 열 이름 행을 접두사로 붙입니다. 당신은 같은 것을 사용하여 데이터 배열에서 키를 사용할 수 있습니다$data = array_merge(array(array_keys($data[0])), $data);
complex857

1
@JoseRojas는 일단 와이어 위에 무언가를 넣으면 (php로 출력하는 것이 개념적으로 의미하는 것) 다시 돌아갈 수 없기 때문에 예상됩니다. 사용하려면 php://output두 번째 업데이트 된 코드 샘플을 참조하십시오.
complex857

18

@ complex857 솔루션에 회신 할만한 평판이 충분하지 않습니다. 훌륭하게 작동하지만 추가해야했습니다. Content-Disposition 헤더의 끝에. 이것이 없으면 브라우저는 파일 이름 끝에 두 개의 대시를 추가합니다 (예 : "export.csv"대신 파일이 "export.csv--"로 저장 됨). 아마도 헤더 행의 끝에서 \ r \ n 삭제를 시도 할 것입니다.

올바른 줄은 다음과 같아야합니다.

header('Content-Disposition: attachment;filename="'.$filename.'";');

CSV에 UTF-8 문자가있는 경우 Content-Type 줄을 변경하여 인코딩을 UTF-8로 변경해야합니다.

header('Content-Type: application/csv; charset=UTF-8');

또한 fseek () 대신 rewind ()를 사용하는 것이 더 우아하다는 것을 알았습니다.

rewind($f);

솔루션에 감사드립니다!


2
내가 경험 한 적이 --그러나 나는 대답 (? 왜 그냥 편집 제출)를 업데이트했습니다, 파일 이름 자신의 말에
complex857

14

시도 ... csv 다운로드.

<?php 
mysql_connect('hostname', 'username', 'password');
mysql_select_db('dbname');
$qry = mysql_query("SELECT * FROM tablename");
$data = "";
while($row = mysql_fetch_array($qry)) {
  $data .= $row['field1'].",".$row['field2'].",".$row['field3'].",".$row['field4']."\n";
}

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="filename.csv"');
echo $data; exit();
?>

필드 값
에이

14

이것이 제가 프로젝트에 사용한 기능이며 예상대로 작동합니다.

function array_csv_download( $array, $filename = "export.csv", $delimiter=";" )
{
    header( 'Content-Type: application/csv' );
    header( 'Content-Disposition: attachment; filename="' . $filename . '";' );

    // clean output buffer
    ob_end_clean();

    $handle = fopen( 'php://output', 'w' );

    // use keys as column titles
    fputcsv( $handle, array_keys( $array['0'] ) );

    foreach ( $array as $value ) {
        fputcsv( $handle, $value , $delimiter );
    }

    fclose( $handle );

    // flush buffer
    ob_flush();

    // use exit to get rid of unexpected output afterward
    exit();
}

1
나는 모든 현재 페이지 html을 csv 파일 끝에 추가 할 때마다 wordpress send_headers 후크에서 구현하려고 노력했습니다. 이 대답은 나를 많이 괴롭히지 만 버퍼 작업없이 사용합니다.
Oleg Apanovich

깨끗한 출력 버퍼는 형성된 파일의 시작과 끝에서 이러한 코드 행을 사용하기 전에 빈 행이었던 문제를 해결했습니다.
Sharunas Bielskis

8

아래 코드를 사용하여 PHP 배열을 CSV로 변환하십시오.

<?php
   $ROW=db_export_data();//Will return a php array
   header("Content-type: application/csv");
   header("Content-Disposition: attachment; filename=test.csv");
   $fp = fopen('php://output', 'w');

   foreach ($ROW as $row) {
        fputcsv($fp, $row);
   }
   fclose($fp);

3

배열 구조가 항상 정확한 방식으로 다차원 적이라면 다음과 같은 요소를 반복 할 수 있습니다.

$fh = fopen('somefile.csv', 'w') or die('Cannot open the file');

for( $i=0; $i<count($arr); $i++ ){
    $str = implode( ',', $arr[$i] );
    fwrite( $fh, $str );
    fwrite( $fh, "\n" );
}
fclose($fh);

그것은 그것을하는 한 가지 방법입니다 ... 수동으로 할 수 있지만이 방법은 더 빠르고 이해하기 쉽고 읽기 쉽습니다.

그런 다음 complex857이 파일을 뱉어내는 작업을 헤더로 관리합니다. 그런 다음 더 이상 필요하지 않은 경우 unlink ()를 사용하여 파일을 삭제 하거나 원하는 경우 서버에 남겨 둘 수 있습니다.


-2

다음을 사용하십시오.

echo "<script type='text/javascript'> window.location.href = '$file_name'; </script>";
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.