Apache Freemarkerで繰り返しサンプル

今さらですが、Apache FreeMarkerを利用する機会がありました。
その時、Mapで繰り返し(Loop)を出力を行う日本語のサンプルが見つからなかったので、メモがてらサンプルを記載します。

#前提
Apache FreeMarker:2.3.28

#出力結果
今回は、HTMLをFreeMarkerを利用して出力します。
出力結果は下図の通りです。

Tableタグと、Table下部の値をFreeMarkerでそれぞれ出力していきます。
![result.png](https://qiita-image-store.s3.amazonaws.com/0/135384/8c6d3ff4-e5a0-24be-1291-476d2b59e927.png)

#pom.xml

```
  <dependencies>
    <!-- FreeMarker -->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.28</version>
    </dependency>
  </dependencies>

````

#template
templateは、[src/main/resource/template.html]に保存します。
Tableタグのtrタグおよび、Tableタグ下の<div>タグを、ListもしくはMapの繰り返しで出力する設定です。

```
<html>
  <span>[table from list]</span>
  <table style="border-collapse: collapse;" cellspacing="1" cellpadding="5">
    <tbody>
      <tr align="center">
        <td style="background-color:#edf5f9;border:1px solid #42B4ED;font-weight: bold;" width="25%">parameter</td>
        <td style="background-color:#edf5f9;border:1px solid #42B4ED;font-weight: bold;" width="18%">value</td>
        <td style="background-color:#edf5f9;border:1px solid #42B4ED;font-weight: bold;" width="57%">comment</td>
      </tr>
      
      <!-- Output rows from java.util.List -->
      <#list itemList as item>
      <tr>
        <td style="border: 1px solid #42B4ED;">${item.param}</td>
        <td style="border: 1px solid #42B4ED;">${item.value}</td>
        <td style="border: 1px solid #42B4ED;">${item.comment}</td>
      </tr>
      </#list>   
    </tbody>
  </table>
  
  <!-- Output a row from java.util.Map -->
  </br>
  <div>[value from map]</div>
  <#list mapValue as key, value>
  <div>
    <span>${key}:${value}</span>
  </div>
  </#list>
</html>

```

#Java

ソースコードは、パーツ(処理のかたまり)毎に記載していきます。

### Parameter for Template

FreeMarkerに渡すパラメータ(可変値)のコーディングは以下の通りです。

```

    //====== Build template parameter ======//
    Map<String, Object> paramMap = new HashMap<>();
      
    // build itemList
    List<Map<String, String>> itemList = new ArrayList<>();
    Map<String, String> itemMap1 = new HashMap<>();
    itemMap1.put("param", "param1");
    itemMap1.put("value", "99.1");
    itemMap1.put("comment", "hogehoge");
    itemList.add(itemMap1);
    Map<String, String> itemMap2 = new HashMap<>();
    itemMap2.put("param", "param2");
    itemMap2.put("value", "98.2");
    itemMap2.put("comment", "hogehoge2");
    itemList.add(itemMap2);
    paramMap.put("itemList", itemList);
    
    // build mapValue
    Map<String, String> mapValue = new HashMap<>();
    mapValue.put("param3", "97.3");
    mapValue.put("param4", "96.4");
    paramMap.put("mapValue", mapValue);
```

ソースだとMapの中身が分かりづらいので、[paramMap]をtoStringした結果もつけておきます。

```xx:paramMap
{
  itemList=[
    {param=param1, value=99.1, comment=hogehoge}, 
    {param=param2, value=98.2, comment=hogehoge2}
  ],
  mapValue={
    param3=97.3, 
    param4=96.4
  }
}
```

### Output 

FreeMarkerのTemplateの初期化および出力処理は以下の通りです。
出力結果は標準出力およびファイル(result.html)に出力しています。

```
    //====== Initialize template ======//
    // New Config
    Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
    
    // Encoding
    cfg.setDefaultEncoding("UTF-8");

    // Set template path
    cfg.setClassLoaderForTemplateLoading(Thread.currentThread().getContextClassLoader(), "/");
  
    //====== Output ======//
    try {

      // Get template
      Template template = cfg.getTemplate("template.html");
      
      // Write to system out
      Writer out = new OutputStreamWriter(System.out);
      template.process(paramMap, out);
      out.flush();
      
      // Write to file
      try (Writer fw = new FileWriter(new File("result.html"))) {
        template.process(paramMap, fw);
        out.flush();
      }
      
    } catch(IOException | TemplateException ex) {
      ex.printStackTrace();
      System.exit(1);
    }
```

#Git

全ソースコードは、[GitHub](https://github.com/yo24/FreeMakerSample1)を参照してください