HTMLのTABLEタグを簡単にCSVファイルに変換する方法

実装のパターンとして一覧で表示されている表を、CSVファイルでダウンロードできるようにすることがあると思います。
このときHTMLをTABLEタグで表示しているものを、CSVで実装しなおすのは手間がかかりますし、表の並び順が変わったり列が追加されたときにHTMLもCSVも変更しなければいけないのは面倒です。

そこでTABLEタグで表示されているHTMLをCSVに変換すると楽になります。

Smartyを使用している場合はアウトプットフィルターを使うだけで、簡単にHTMLがCSVになります。
Smartyに実装する方法

[参考記事] Excelで保存したときのCSVファイルの仕様
[参考記事] 複雑なExcelファイルをプログラムで作成する方法

実現方法

PHPでは、次のコードで実装し、出力される前に次の関数table_tag2csv()を通します。

コード

/* ================================
 * table_tag2csv
 *
 * @create  2010/04/09
 * @author  pentan
 * @url     http://pentan.info/
 *
 * Copyright (c) 2009 pentan.info All Rights Reserved.
 * 著作権表示部分の変更削除は禁止です
 * ================================
 */
function table_tag2csv($buff) {
  $buff = preg_replace("/>[\s]+</is","><",$buff);

  $buff = preg_replace("/^.*<table[^>]*>/Uis","",$buff);
  $buff = preg_replace("/<\/table>.*$/is","",$buff);

  $buff = preg_replace("/<([a-z]+) ([^>]+)>/i","<$1>",$buff);
  $buff = preg_replace("/<th>/i","<td>",$buff);
  $buff = preg_replace("/<\/th>/i","</td>",$buff);

  $buff = preg_replace("/<\/?[^(tr|td)<>]+>/i","",$buff);

  $buff = str_replace("\r\n","\n",$buff);
  $buff = preg_replace("/(\r|\n)/","\r\n",$buff);

  $csv = "";
  if(preg_match_all("/<tr>(.*)<\/tr>/iU",$buff,$trmatches)){
    foreach($trmatches[1] as $rows){
      if(preg_match_all("/<td>(.*)<\/td>/iU",$rows,$tdmatches)){
        for($i=0;$i<count($tdmatches[1]);$i++){
          if(strpos($tdmatches[1][$i],",")!==false || strpos($tdmatches[1][$i],'"')!==false || strpos($tdmatches[1][$i],"\r\n")!==false){
            $tdmatches[1][$i] = '"'.str_replace('"','""',$tdmatches[1][$i]).'"';
          }
          $tdmatches[1][$i] = htmlspecialchars_decode($tdmatches[1][$i]);
        }
        $csv .= implode(',',$tdmatches[1]);
      }
      $csv .= "\r\n";
    }
  }

  header('Cache-Control: private, max-age=10800, pre-check=10800');
  header('Content-Disposition: attachment; filename="'.date("Y-m-d").'.csv"');
  header('Pragma: no-cache');
  header('Content-Type: text/comma-separated-values');
  header('Content-Length: ' . strlen($csv));

  return $csv;
}

使い方

実行部

<?php
if(!($fp = @fopen("index.html","r"))) {
  die;
}

$data="";
while (!feof($fp)) {
  $data.=fgets($fp, 4096);
}
fclose($fp);

$data = table_tag2csv($data);

echo $data;

Smartyに実装する方法

Smartyでは、アウトプットフィルターにこの関数を指定することで、出力がフィルタリングされます。

$smarty->register_outputfilter("table_tag2csv");

関連記事

スポンサーリンク

WinSCPでリスト取得のエラー『ディレクトリのリストに不正な行 'ケ邱ラ' 不正な権限の表記』

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る