HTML、JavaScriptを扱う人を対象に投稿しています。
要件
<ul>
<li>カテゴリA
<ul>
<li><a href="DUMMY">カテゴリAの商品1</a></li>
<li><a href="DUMMY">カテゴリAの商品2</a></li>
<li><a href="DUMMY">カテゴリAの商品3</a></li>
</ul>
</li>
<li>カテゴリB
<ul>
<li><a href="DUMMY">カテゴリBの商品1</a></li>
<li><a href="DUMMY">カテゴリBの商品2</a></li>
<li><a href="DUMMY">カテゴリBの商品3</a></li>
</ul>
</li>
</ul>
といった、ネストされた<ul><li>
のHTMLを作るという要件で、カテゴリ、URL、商品名が、みっちりぎっしり大量に記載されたExcelファイルを渡されたとします。
そのExcelファイルが下記の書式(1行につき1商品)だったら、どうしますか?
実装方法
まさか手作業でHTML化するわけにはいきません。
ExcelのデータをJSONに書き出して、JavaScriptでHTMLを組み立てる方法を検討しました。
(他の言語を用いれば、もっと早くできるかもしれませんが、HTML、jQueryを扱う人向けの提案です)
問題はネストの部分。
このExcelの書式では、下記のような入れ子のJSONを作ることが難しそうです。
[
{
"category":"カテゴリA",
"product":[
{"name":"カテゴリAの商品1", "url":"http://XXX/a_01.html"},
{"name":"カテゴリAの商品2", "url":"http://XXX/a_02.html"},
{"name":"カテゴリAの商品3", "url":"http://XXX/a_03.html"}
]
},
{
"category":"カテゴリB",
"product":[
{"name":"カテゴリBの商品1", "url":"http://XXX/b_01.html"},
{"name":"カテゴリBの商品2", "url":"http://XXX/b_02.html"},
{"name":"カテゴリBの商品3", "url":"http://XXX/b_03.html"}
]
},
{
"category":"カテゴリC",
"product":[
{"name":"カテゴリCの商品1", "url":"http://XXX/c_01.html"},
{"name":"カテゴリCの商品2", "url":"http://XXX/c_02.html"},
{"name":"カテゴリCの商品3", "url":"http://XXX/c_03.html"}
]
}
]
そこで入れ子のJSONを作らずに、Excel1行につき、1オブジェクトとしたJSONからHTMLを出力させます。
作業1. ExcelデータのJSON化
ExcelデータをJSON化するには様々な手段がありますが、以下の方法を用いました。
- 元Excelのラベル(「カテゴリ名」「商品名」「URL」)をキーに変更(「category」「name」「url」)
- 元ExcelをCSVデータとして保存
- CSV to JSON - CSVJSON http://www.csvjson.com/csv2json でコンバート
下記のJSONファイルを素早く準備できました。
sample.json
[
{
"category": "カテゴリA",
"name": "カテゴリAの商品1",
"url": "http://XXX/a_01.html"
},
{
"category": "カテゴリA",
"name": "カテゴリAの商品2",
"url": "http://XXX/a_02.html"
},
{
"category": "カテゴリA",
"name": "カテゴリAの商品3",
"url": "http://XXX/a_03.html"
},
{
"category": "カテゴリB",
"name": "カテゴリBの商品1",
"url": "http://XXX/b_01.html"
},
{
"category": "カテゴリB",
"name": "カテゴリBの商品2",
"url": "http://XXX/b_02.html"
},
{
"category": "カテゴリB",
"name": "カテゴリBの商品3",
"url": "http://XXX/b_03.html"
},
{
"category": "カテゴリC",
"name": "カテゴリCの商品1",
"url": "http://XXX/c_01.html"
},
{
"category": "カテゴリC",
"name": "カテゴリCの商品2",
"url": "http://XXX/c_02.html"
},
{
"category": "カテゴリC",
"name": "カテゴリCの商品3",
"url": "http://XXX/c_03.html"
}
]
作業2. HTML、jQueryコードの作成
sample.jsonからHTMLを組み立てるコードを書きます。
HTML、jQuery
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
<script
src="https://code.jquery.com/jquery-3.1.1.js"
integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
crossorigin="anonymous"></script>
</head>
<script>
$.getJSON('sample.json', {}, function(json){
// 変数の宣言
var htmlString = '';
var htmlStringWrap = '';
var prevCategory = '';
var category = '';
$.each(json, function(i, obj){
// 直前のループにおける変数「category」を「prevCategory」に代入(ループ初回時の値は初期値の「''」)
prevCategory = category;
// キー「category」の値を変数「category」に代入
category = obj.category;
// ループのたびに変数「htmlStringWrap」を初期化
htmlStringWrap = '';
// 【第1階層の<li>を作成】「prevCategory」と「category」の値が異なる場合に、<ul>を内包する<li>を、変数「htmlStringWrap」にセット
// ループ初回の「\n</ul>\n</li>」はinvalidなHTMLのため、無視される
if (category !== prevCategory) {
htmlStringWrap = '\n</ul>\n</li>\n<li>' + category + '\n<ul>';
}
// 【第2階層の<li>を作成】ループを回し、obj.url と obj.name に基づいたリンクを内包する<li>を、変数「htmlStringWrap」と連結して、変数「htmlString」に順繰りに追加
htmlString += htmlStringWrap + '\n<li><a href="' + obj.url + '">' + obj.name + '</a></li>';
});
// JSONを元に形成したHTML(変数「htmlString」)を<ul id="link">~</ul>内に追加
$('#link').html(htmlString);
});
</script>
</head>
<body>
<ul id="link">
</ul>
</body>
</html>
出力結果
<ul id="link">
<li>カテゴリA
<ul>
<li><a href="http://XXX/a_01.html">カテゴリAの商品1</a></li>
<li><a href="http://XXX/a_02.html">カテゴリAの商品2</a></li>
<li><a href="http://XXX/a_03.html">カテゴリAの商品3</a></li>
</ul>
</li>
<li>カテゴリB
<ul>
<li><a href="http://XXX/b_01.html">カテゴリBの商品1</a></li>
<li><a href="http://XXX/b_02.html">カテゴリBの商品2</a></li>
<li><a href="http://XXX/b_03.html">カテゴリBの商品3</a></li>
</ul>
</li>
<li>カテゴリC
<ul>
<li><a href="http://XXX/c_01.html">カテゴリCの商品1</a></li>
<li><a href="http://XXX/c_02.html">カテゴリCの商品2</a></li>
<li><a href="http://XXX/c_03.html">カテゴリCの商品3</a></li></ul></li></ul>
補足
ループ初回の「</ul></li>
」はinvalidなHTMLのため、無視されます。
<ul id="link">
</ul>
</li>
<li>カテゴリA
<ul>
<li><a href="http://XXX/a_01.html">カテゴリAの商品1</a></li>
<li><a href="http://XXX/a_02.html">カテゴリAの商品2</a></li>
<li><a href="http://XXX/a_03.html">カテゴリAの商品3</a></li>
</ul>
</li>
【中略】
<li>カテゴリC
<ul>
<li><a href="http://XXX/c_01.html">カテゴリCの商品1</a></li>
<li><a href="http://XXX/c_02.html">カテゴリCの商品2</a></li>
<li><a href="http://XXX/c_03.html">カテゴリCの商品3</a></li></ul></li></ul>
にはなりません。
参照: innerHTML や jQuery.html() は HTMLをそのまま取得できるわけではない
静的HTMLとして保存したい場合
2つの方法をとることができます。
- ブラウザの「名前を付けて保存」で、ファイルの種類を「ウェブページ、完全」とすると、HTMLが出力された状態のファイルを取得できます。
- 開発ツールでDOM要素を右クリック「Copy > Copy outerHTML」し、必要な範囲をコピー。
支給されたデータを、あれやこれや加工してしまうと、データに齟齬が生じてしまうのではないかと考えました。
支給データはなるべくいじらず、省エネモードで、さくさくとHTMLを作成する、そんなコーダーでありたいと思います。