grunt-mustache-renderを使ってエクセルからhtmlを量産したい！

エクセルのデータからhtmlファイルを大量に作成する案件があったので、
その時のことをメモ兼ねて書いてみました。

#はじめに
今回はGruntで作業を行ったので、Gruntでの方法になってます。
主なモジュールはコレ

・grunt-mustache-render
・xlsx

簡単な構成としては、下記な感じです。
(1) xlsxモジュールでデータを取り出し
(2) grunt-mustache-renderで使えるようにデータを整形
(3) grunt-mustache-renderでファイル生成

#各種設定
##エクセルファイルのフォーマット
![ss01.png](https://qiita-image-store.s3.amazonaws.com/0/65924/d30a4d68-dcff-2906-b859-427383a253c5.png)

１行目をヘッダー、
２行目以降が生成ファイルのデータ（１レコード１ファイル）
でエクセルを作成してます。

##テンプレートの設定
```template.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>{{タイトル}}</title>
	<link rel="stylesheet" href="/css/{{パラメータ1}}_{{パラメータ2}}_{{パラメータ3}}.css">
</head>
<body>
	<header>
		<h1>{{タイトル}}</h1>
	</header>
	<div>
		<img src="{{&画像}}" alt="{{タイトル}}">
	</div>
</body>
</html>
```
{{ }}で括ってる部分がエクセルからのデータを流し込む箇所になります。
{{ }}の中の名前はエクセルで作成したヘッダー名で指定しましょう。

##Gruntの設定
```Gruntfile.js
'use strict';
var XLSX = require('xlsx');
module.exports = function(grunt) {
  grunt.initConfig({
    clean: {
        run: ['./output']
    },
    mustache_render: {
        run: {
            files: (function() {
                // 設定
                var inpFile = 'サンプル.xlsx';
                var inpSheet = 'Sheet1';

                // ファイル読み込み
                var data = XLSX.readFile(inpFile);
                var sheet = data.Sheets[inpSheet];

                // ファイル内容整形
                var json = XLSX.utils.sheet_to_json(sheet);

                var files = [];
                for (var i=0, j=json.length; i<j; i++){
                    var pageData = json[i];

                    // files配列にオブジェクトを追加
                    files.push({
                        // ページデータ
                        data: pageData,
                        // テンプレートファイルを指定
                        template: './template.html',
                        // 生成するhtmlの場所と名前を設定
                        dest: './output/' + pageData.パラメータ1 + '_' + pageData.パラメータ2 + '_' + pageData.パラメータ3 + '.html'
                    });
                }
                // 配列を返却
                return files;
            }())
        }
    }
  });
  grunt.loadNpmTasks('grunt-mustache-render');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.registerTask('run', ['clean', 'mustache_render']);
};
```
cleanを導入してますけど、これは好みでどうぞ。
上記ではファイルを生成する前に一度ディレクトリの中を空にしてます。

```Gruntfile.js(抜粋1)
// 設定
var inpFile = 'サンプル.xlsx';
var inpSheet = 'Sheet1';
```
上記の部分では、
inpFileでは読み込み対象のエクセルを指定し、
inpSheetでは上記ファイル内のシート名を指定しています。

ちなみに、今回は特に設定をしていないため、ルートのディレクトリはGruntfile.jsが置いてる階層となってます。

```Gruntfile.js(抜粋2)
// files配列にオブジェクトを追加
files.push({
  // ページデータ
  data: pageData,
  // テンプレートファイルを指定
  template: './template.html',
  // 生成するhtmlの場所と名前を設定
  dest: './output/' + pageData.パラメータ1 + '_' + pageData.パラメータ2 + '_' + pageData.パラメータ3 + '.html'
});
```
こちらのブロックでは、
実際にファイルを出力する際のデータを整形しています。

なお、`data: pageData,`では読み込んだエクセルの１レコード分のデータが格納されてます。
各レコード内のパラメータへのアクセスは、
`pageData.[パラメータ名]`
で可能です。

パラメータを加工する必要がある場合は、
このブロックで行いましょう。
もちろん`pageData`へのパラメータ追加も可能です。

#いざ実行
上記の設定では

```
grunt run
```
でタスクが実行されます。

##生成されたファイル
```001_A01_BS000.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>サンプル１</title>
	<link rel="stylesheet" href="/css/001_A01_BS000.css">
</head>
<body>
	<header>
		<h1>サンプル１</h1>
	</header>
	<div>
		<img src="/img/sample01.png" alt="サンプル１">
	</div>
</body>
</html>
```

とりあえず、こんな方法もあるよということで〜

#サンプル
今回作成したサンプルデータをgithubにアップしています。
https://github.com/kurokuma29/xlsx-render