用PHP將資料轉成CSV格式檔案

Table of Contents

Table of Contents

用PHP處理資料後,除了在畫面上顯示外,能夠轉成CSV格式檔案後下載到電腦上是常常有的情況。
本文將介紹使用PHP實現CSV檔案下載。範例是在Laravel的框架中實現,但只要知道原理後在其他的應用框架中也能實現。

目標

從DB中取出資料,然後將資料轉成csv檔案下載。

程式碼

// CSVExportController.php

public function csvExport()
{
  $contents = Post::all();
  if (count(contents) == 0) {
    $response = new StreamedResponse(function() {});
    $filename = 'no_data.csv';
  } else {
    $header = array_keys($contents[0]->toArray());
    $response = $this->csvExportResponse('output.csv', $contents, $header);
  }
  return response;
}

public function csvExportResponse($fileName, $contents, $header=NULL)
{
  $response = new StreamedResponse(function() use ($contents, $header) {
    $stream = fopen('php://output', 'w');
    if ($header) {
      fputcsv($stream, $header);
    }
    foreach($contents as $data) {
      $row = [];
      foreach($header as $headerItem) {
        $row[] = $data->{$headerItem};
      }
      fputcsv($stream, $row);
    }
    fclose($stream);
  });
  $response->headers->set('Content-type', 'text/csv');
  $response->headers->set('Content-Disposition', "attachment; filename=$fileName");
  $response->headers->set('Cache-Control', 'no-cache, must-revalidate');
  $response->headers->set('Pragma', 'no-cache');
  $response->headers->set('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT');
  return $response;
}

說明

csvExport中處理Http Request,從DB中取得資料,然後把資料傳給csvExportResponse執行轉換CSV檔案的處理。

csvExportResponse中主要用fopenfputcsv生成StreamedResponse
StreamedResponse的構造函數中第一個參數是callback函數,主要用來處理csv檔案的內容。
第二個參數是代表response status code
第三個參數是response headers,設置reponse的標頭參數。

補充

如果有將utf-8轉換成其他文字編碼的需要,可以參考使用mb_convert_variables
主要做法是,先將文字做完轉碼後在使用fputcsv,把內容放到csv檔案之中。

參考

StreamedResponse