LoginSignup
6
1

More than 5 years have passed since last update.

PHPでTSVを出力し、直接ダウンロードする

Last updated at Posted at 2019-03-04

はじめに

DBを使っていて、取得したデータを適当に加工してグラフ化するってことは業務アプリなどでは多々ある作業です。
また、その取得したデータをEXCELなどで見たいってなることもよくある話です。
だいたいそういう時は、CSV(コンマ区切り)かTSV(タブ区切り)で保存するっぽいです。
そこで、備忘録として、DBから取得したデータをTSV形式に変換する方法をまとめました。

方法

1.データ作成

まずは出力したいデータを作成します

aaa.php
   $title = 'フルーツの値段';
   $datas = array(
       'name' => 'りんご'
       , 'price' => 120
       , 'area' => 'トルコ'
     );

2.文字コード変換

このまま出力すると文字化けしちゃうので、文字コードの変換をします。
使用するのは、mb_convert_variables関数です。

mb_convert_encoding関数は、文字列を指定の文字コードに変換するのに対し、
mb_convert_variables関数は、配列に格納された文字列を順繰りと変換してくれます。

aaa.php
   $title = mb_convert_encoding($title, 'SJIS', 'UTF-8');
   mb_convert_variables('SJIS', 'UTF-8', $datas);

mb_convert_encoding関数
第1引数:変換したい文字列
第2引数:変換後の文字コード
第3引数:変換前の文字コード

mb_convert_variables関数
第1引数:変換後の文字コード
第2引数:変換前の文字コード
第3引数:変換したい配列
*第3引数は参照渡しになっているので注意!

なんで引数こんなにぐっちゃぐちゃなの

3.ファイル出力のヘッダー

ファイルをダウンロードできるようにするためには、HTMLヘッダーを記述しなければいけません。

aaa.php
   $fileName = $title . '.tsv';

   header('Content-Type: application/octet-stream');
   header('Content-Disposition: attachment; filename=' . $fileName);

4.書き込み

いよいよ書き込みです。
流れとしては、

  1. ファイルオープン
  2. 書き込み
  3. ファイルクローズ

です。
どの言語でも一緒か…

aaa.php
   //「php://output」に出力することで、一時ファイルを作成せずに書き込みができる。
   $handle = fopen('php://output', 'w');
   fputcsv($handle, $datas, "\t");
   fclose($handle);

   //ここでexitしないとHTML情報も書き込まれてしまう
   exit();

fputcsv関数
第1引数:fopenのファイルポインタ
第2引数:書き込む配列
第3引数:区切り文字(指定しない場合はカンマ[,])
*CSVで出力する場合は、第3引数を指定する必要がない

5.仕上げ

HTMLの部分で、ボタン発火とかしてあげればいいと思います。

まとめ

ざっとこんな感じです。
複数の配列を書き込みたい場合は、fopenとfcloseの間にfputcsv関数を並べればいいと思います。
その際は行間が入らないので、適当に空の配列でもかましてあげたりすればいいと思います。

多次元配列の場合は、foreachで回せばいいと思います。

以下に全部つなげたコードを貼っておきます。

aaa.php
   //データ作成
   $title = 'フルーツの値段';
   $datas = array(
       'name' => 'りんご'
       , 'price' => 120
       , 'area' => 'トルコ'
     );

   //文字コード変換
   $title = mb_convert_encoding($title, 'SJIS', 'UTF-8');
   mb_convert_variables('SJIS', 'UTF-8', $datas);

   //ファイル名決定
   $fileName = $title . '.tsv';

   //HTMLヘッダー
   header('Content-Type: application/octet-stream');
   header('Content-Disposition: attachment; filename=' . $fileName);

   //ファイルへの書き込み
   //「php://output」に出力することで、一時ファイルを作成せずに書き込みができる。
   $handle = fopen('php://output', 'w');
   fputcsv($handle, $datas, "\t");
   fclose($handle);

   //ここでexitしないとHTML情報も書き込まれてしまう
   exit();

あとがき

はじめての投稿です。
Markdown方式で初めて書くので、ちょっと使い方わかんないですね。
あと、タブ区切りが使えないのもコーダーにとっては致命的だなと思いました。
え?もしかして俺が知らないだけ?

わかりにくいところなどあれば、ご教授願います。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1