人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

CSVをHTML化する際での質問です。



CSVをHTML化したいのですが、上下に同じデータが入っている場合は結合して出力したいのです。
PHPをうまく利用してできませんか?(イメージ図を添付)


こういうのは見つけたのですが、

「エクセルシートをHTMLテーブルに変換しちゃう君 」がすごく便利
http://web-marketing.zako.org/web-tools/henkankun-html-tables-from-excel.html

CSVデータが随時変更になるので、変換も自動で行えるような運用にしたいと思いPHPでHTMLソースコードを書きたいと思います。


参考になるサイトなどご存知ありませんか?

1285677495
●拡大する

●質問者: petem
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:CSV HTML PHP イメージ エクセル
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● Numeric
●60ポイント ベストアンサー

あまりスマートではありませんが、わかりやすさを優先して書いてみました。

が、まさか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: str_getcsv - Manualより転載

<?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>
◎質問者からの返答

うおぉ


すごい。。。

まさかここまでキッチリと答えてもらえるとは。。。

ありがとうございます。

試してみます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ