【vte.cx応用】21.サーバーサイドJavascriptを使用したPDF出力の方法


今回はサーバーサイドjavascriptを使用したPDFの出力と、その書き方の仕方について説明します。

# vtecxblankを最新の状態にしてください
PDF出力は古いバージョンのvtecxblankプロジェクトだと動作しません。
お手数ですが、vtecxblankプロジェクトを最新にしていただきますようよろしくお願い致します。
(2015/12/18付)


# PDFのサンプルソース
PDFを出力する際は、HTMLとリソースデータが必要になります。
HTMLで型となるテンプレートを作成し、そのテンプレートにリソースデータの値を代入して出力するイメージとなります。

このリソースデータをpdfとして出力するとします。

```lang:/d/hoge（リソースデータ）
    {
    	feed: {
    		entry:[{
    			title: 'Hello World',
    			link: [{
    				___href: '/hoge',
    				___rel: 'self'
    			}],
    			id: '/hoge,1'
    		}]
    	}
    }
```

リソースデータのtitle項目の「Hello World」をPDFとして出力したい場合、以下のようなHTMLをテンプレートとして用意してください。

```lang:hello_world.html（HTMLテンプレート）
<?xml version="1.0" encoding="UTF-8" ?>
<html>
<body>
    <!-- 用紙サイズ指定：（A4・縦） -->
    <div class="_page" style="pagesize:A4; orientation:portrait;">
        <table>
            <tr>
                <td>
                    <!-- 表示させたい値の項目名をidに定義します -->
                    <p id="title" />
                </td>
            </tr>
        </table>
    </div>
</body>
</html>
```

「_page」クラスのstyleに用紙サイズと用紙の向きを指定することができます。

## テンプレートのHTMLの保存場所
テンプレートのHTMLはvtecxblankプロジェクトの以下の場所に配置してください。

```lang:ファイルの置き場所
   /app/pdf
      hello_world.html
```

# サーバーサイドjavascriptでReflexContext.toPdf()を実行する

PDFを作成し出力するためにはサーバーサイドjavascriptが必要になります。
ReflexContext.toPdf()メソッドを使用することでPDFを出力できます。

以下のサーバーサイドjavascriptを用意してください。

```lang:test.pdf.js（サーバーサイドjavascript）
module.exports = function () {

  // リソースデータ取得
  var data = ReflexContext.getEntry('/hoge');

  // PDF出力
  ReflexContext.toPdf(data, '/pdf/hello_world.html', 'test.pdf');

};
```

ReflexContext.toPdfメソッドの引数は以下のようになります。

```
    ReflexContext.toPdf({リソースデータ}, {HTMLのURL}, {PDFのファイル名（拡張子含む）})
```

# デプロイを実行し、実際にアクセスしてみる

* hello_world.html（テンプレートHTML）
* test.pdf.js（サーバーサイドjavascript）

をapp配下に置いたら、デプロイを実行したら、以下のURLでアクセスしてみてください。

```lang:アクセスURL
   /s/test.pdf
```

するとPDFが表示（またはダウンロード）されると思います。

# ファイル名を指定しないとブラウザに表示できます
ReflexContext.toPdfのファイル名の指定をnullにするとブラウザにPDFを表示できます。

```lang:test.pdf.js（サーバーサイドjavascript）
module.exports = function () {

  // リソースデータ取得
  var data = ReflexContext.getEntry('/hoge');

  // PDF出力
  ReflexContext.toPdf(data, '/pdf/hello_world.html', null);

};
```


# グローバルなoutput_pdf.jsを作成する
一つのPDFファイルに対して一つのサーバーサイドjavascriptを作成するのは何かと手間になるケースがあります。そういうときはpdf作成用の共通したサーバーサイドjavascriptを作成するといいと思います。

```lang:PDF作成用のサーバーサイドjavascript
GET /s/output_pdf?data=/hoge&template=/pdf/person_template.html&name=test.pdf

// output_pdf.js
module.exports = function () {

  var querystring = ReflexContext.querystring();

  // 各パラメータ取得
  var data_path = querystring.split('&')[0].replace('data=', '');
  var template_path = querystring.split('&')[1].replace('template=', '');
  var pdf_name = querystring.split('&')[2].replace('name=', '');

  // リソースデータ取得
  var data = ReflexContext.getEntry(data_path);

  ReflexContext.toPdf(data, template_path, pdf_name);

};
```

こうすることで、引数により生成するPDFを変更することができます。

# テンプレートHTMLにCSSを適用する
テンプレートHTMLにはスタイルを適用することができます。
これは通常のCSSと指定方法に変わりはありません。

```lang:helloworld.css

#title {
    color: red;
}

```

```lang:CSS適用
<?xml version="1.0" encoding="UTF-8" ?>
<html>
<head>

    <!-- linkタグにスタイルシートを指定できます -->
    <link rel="stylesheet" href="helloworld.css" media="all" type="text/css"></link>

</head>
<body>
    <div class="_page" style="pagesize:A4; orientation:portrait;">
        <table>
            <tr>
                <td>
                    <p id="title" />
                </td>
            </tr>
        </table>
    </div>
</body>
</html>

```


# より詳しい仕様はこちらで確認できます。

テンプレートのHTMLタグには使用可能なタグが決められていたり、また様々な機能がPDF出力には備えられています。
詳しい仕様は[こちら](http://reflexworks.jp/documentation.html#reflexitext.html#A)をご覧ください。

以上でPDF出力の説明を終わります。