CSVをHTML化したいのですが、上下に同じデータが入っている場合は結合して出力したいのです。
PHPをうまく利用してできませんか?(イメージ図を添付)
こういうのは見つけたのですが、
↓
「エクセルシートをHTMLテーブルに変換しちゃう君 」がすごく便利
http://web-marketing.zako.org/web-tools/henkankun-html-tables-from-excel.html
↓
CSVデータが随時変更になるので、変換も自動で行えるような運用にしたいと思いPHPでHTMLソースコードを書きたいと思います。
参考になるサイトなどご存知ありませんか?
あまりスマートではありませんが、わかりやすさを優先して書いてみました。
が、まさかstr_getcsv()が実装されていないとは思わず…(環境によるのかな?)
素直にfgetcsv()を使うべきだったなぁと思いました。
csv2table.php
<?php include_once("str_getcsv.php"); echo csv2table("sample.csv"); function csv2table($csvFilename){ $csvData = str_getcsv(file_get_contents($csvFilename)); $table = array(); //セルのHTMLタグ $nrow = count($csvData); //行数 $ncol = count($csvData[0]); //列数 for($col=0;$col<$ncol;$col++){ for($row=0;$row<$nrow;){ $cell = trim($csvData[$row][$col]); //セルの内容 $mergeCnt = 1; //結合するセルの数 //現在のセルから下に向かって、同じものがあるか調べる for($search=$row+1;$search<$nrow;$search++){ if(trim($csvData[$search][$col]) == $cell){ $mergeCnt++; } else{ break; } } //同じデータが2つ以上続いていたらマージ $rowspan = (2 <= $mergeCnt)?" rowspan='".$mergeCnt."'":""; //tdタグを生成し、セルごとに配列に保存する。 $table[$row][$col] = "<td".$rowspan.">".$cell."</td>"; //結合した分だけ下がる $row += $mergeCnt; } } ksort($table); //行が乱れている場合があるので整える。 //出力データ生成 $result = "<table>\n"; foreach($table as $row => $cols){ $result .= "<tr>"; $result .= implode("", $cols); $result .= "</tr>\n"; } $result .= "</table>"; return $result; } ?>
str_getcsv.php
<?php if (!function_exists('str_getcsv')) { function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') { if (is_string($input) && !empty($input)) { $output = array(); $tmp = preg_split("/".$eol."/",$input); if (is_array($tmp) && !empty($tmp)) { while (list($line_num, $line) = each($tmp)) { if (preg_match("/".$escape.$enclosure."/",$line)) { while ($strlen = strlen($line)) { $pos_delimiter = strpos($line,$delimiter); $pos_enclosure_start = strpos($line,$enclosure); if ( is_int($pos_delimiter) && is_int($pos_enclosure_start) && ($pos_enclosure_start < $pos_delimiter) ) { $enclosed_str = substr($line,1); $pos_enclosure_end = strpos($enclosed_str,$enclosure); $enclosed_str = substr($enclosed_str,0,$pos_enclosure_end); $output[$line_num][] = $enclosed_str; $offset = $pos_enclosure_end+3; } else { if (empty($pos_delimiter) && empty($pos_enclosure_start)) { $output[$line_num][] = substr($line,0); $offset = strlen($line); } else { $output[$line_num][] = substr($line,0,$pos_delimiter); $offset = ( !empty($pos_enclosure_start) && ($pos_enclosure_start < $pos_delimiter) ) ?$pos_enclosure_start :$pos_delimiter+1; } } $line = substr($line,$offset); } } else { $line = preg_split("/".$delimiter."/",$line); /* * Validating against pesky extra line breaks creating false rows. */ if (is_array($line) && !empty($line[0])) { $output[$line_num] = $line; } } } return $output; } else { return false; } } else { return false; } } } ?>
sample.csv
a,b,c,d a,b,b,e a,c,b,f
出力結果
<table> <tr><td rowspan='3'>a</td><td rowspan='2'>b</td><td>c</td><td>d</td></tr> <tr><td rowspan='2'>b</td><td>e</td></tr> <tr><td>c</td><td>f</td></tr> </table>
うおぉ
すごい。。。
まさかここまでキッチリと答えてもらえるとは。。。
ありがとうございます。
試してみます。