注記
このプラグインのバージョン1.0からアップグレードされる方は、
テンプレートを調整するためにいくつかの変更が必要となりますので、
必ずアップデートガイドをよくお読みください。
使用方法
PDFが好きじゃない人なんていないでしょう? ネイティブのウェブページも素晴らしいですが、
結局のところ、ダウンロードや保存が必要なコンテンツには、
PDFが必要になることもあります。残念ながら、これまで
動的なPDFをその場で生成するのは難しいことでした。高品質なHTML→PDF
コンポーネントはオープンソースではないため、この機能はプラグインとして提供されています。
実は、このプラグインにはPDFを作成するためのツールが
1つだけというわけではありません。3つも用意されています。そう、3つです。
- Lava To PDF ブロック – このブロックをページに配置すると、シンプルな Lava テンプレートから PDF を作成できます。
- PDF ファイルの結合 – Rock Core は Word および HTML ファイルの結合に対応しており、これからは PDF ファイルもその対象に加わりました!
- 「Lava to PDF」ワークフローアクション – このワークフローアクションは、Lavaテンプレートを基にPDFドキュメントを作成し、それを属性として保存します。
「Lava To PDF」ブロック
PDFを作成するには、新しいページを作成し、そのページに「Lava
To PDF」ブロックを追加するだけです。フォーマット済みの
HTMLファイルを生成するLavaテンプレートを指定すれば、PDFが完成します。これほど簡単です。でも、それだけではありません。
機能は山ほどあります……
機能の詳細に入る前に、管理者としてPDFの書式設定を行う際に役立つ
1つのポイントを確認しておきましょう。「Lava 2 PDF」ブロックに対する
管理者権限をお持ちの場合、PDFファイルが
直接表示されることはありません。その代わりに、PDFへのリンクが表示されます。 この
機能が提供されていなければ、ブロック設定を表示できなくなるため、
実質的にPDFの編集ができなくなってしまいます。また、
「デバッグを有効にする」というブロック設定を使用して、
利用可能なマージフィールドの一覧を表示できるようにしてください。

ブロックの設定
以下は、ドキュメント作成時に利用可能な
ブロック設定の一覧です。
- 有効なLavaコマンド [デフォルト:なし]
- PDFの作成に必要なデータが何であるかは分からないため、Lavaコマンドを使用してデータを直接取得する必要があります。これらのコマンドがなければ、このブロックはあまり役に立ちません。少し考えてみて、この機能の威力を理解してください。 SQLやRock Entitiesを使ってRockからデータを取得して美しいドキュメントを印刷したり、C#を呼び出してデータを取得したり、REST呼び出しを行ってサードパーティのシステムからデータを取得したりすることも可能です。この最後の選択肢は、きっとあなたを驚かせることでしょう。PCOからデータを取得し、ウェブサイト上で参加者一人ひとりに合わせたパーソナライズされた情報を提供することを想像してみてください!
- 文書の幅 [デフォルト:8.5]
- この機能については、説明して皆さんの知性を侮るようなことはしません。ただ、単位はインチで、小数も入力できるということだけ知っておいてください。
- 文書の高さ [デフォルト: 11]
- 君ならできるよ…
- 文書名 [デフォルト: document.pdf]
- これは、ユーザーがファイルをダウンロードした際のファイル名になります。Lava形式も対応しているため、「contribution-report.pdf」という名前を使う必要はなく、「contributions-ted-decker-2017.pdf」といった名前を付けることができます。
- 文書テンプレート [Default: <sample>]
- これは、ドキュメントを作成するためのHTML/Lavaテンプレートです。HTMLやCSSを作成する際は、以下のヒントを必ずお読みください。
- インラインで開く [デフォルト: True]
- これにより、ブラウザでのファイルの開き方が決まります。PDFのインライン表示が有効な状態でページが読み込まれると、PDFファイルがブラウザ内に表示されます。インライン表示が無効な状態でリンクをクリックすると、PDFファイルがダウンロードされ、リンクを含むページはブラウザに残ったままになります。これは、「Lava To PDF」ブロックをホストしているページが一切表示されないため、非常にクールな効果です。
- ドキュメントのレンダリング遅延 [デフォルト: 0]
- これは、PDFのレンダリングを開始する前に待機する遅延時間(秒単位、小数点以下なし)を設定します。外部フォントのダウンロードやスクリプトの実行を待つ必要がある場合(Googleマップの読み込みなど)に役立ちます。
- ブックマークの自動作成 [デフォルト: False]
- これにより、HTML内のh1~h6タグからPDFのブックマークが作成されます。
- デバッグを有効にする [デフォルト: False]
- Rockの多くのブロックと同様に、利用可能なマージフィールドを表示するデバッグモードが用意されています。グローバル属性、ページパラメータ、現在の担当者、キャンパスなどの情報にアクセスできます。また、iFrame内でドキュメント(ヘッダーとフッターを除く)を表示することもできます。
- ヘッダー/フッター [デフォルト:無効]
- 次に、ヘッダーとフッターに関する設定があります。両方の設定は同じですので、まとめて説明します:
- 有効にする – 表示するかどうか
- テンプレート – 各要素用のHTMLテンプレートです。ただし、これらは完全なHTMLドキュメントというわけではありません。ドキュメントテンプレートのスタイルやリソースにはアクセスできませんが、Lavaにはアクセスできます。
- 高さ – これは、ヘッダーとフッターの高さ(インチ単位)です。
- 余白 – これは、ヘッダー/フッターと文書本文との間の間隔の高さ(インチ単位)です。
- 背景色 – もちろん、テンプレートでスタイルを設定することも可能ですが、もう少し簡単に設定できるよう、設定項目を用意しました。
ヒントとコツ
以下に、見栄えのする
文書を作成するためのヒントやコツをいくつかご紹介します。
- 表がページをまたぐ際に表の見出しを繰り返し表示しないようにする設定はありますが、CSS を使用して表ごとにこの動作を無効にすることも可能です。その場合は、thead および tfoot タグに style="display: table-row-group" を追加してください。
- HTML要素のスタイルで「page-break-before:always」および「page-break-after:always」というCSS属性を使用することで、PDF内で強制的に改ページを行うことができます。「page-break-before:always」属性は、要素が通常レンダリングされる位置の直前に、PDFページ内で強制的に改ページを行います。また、「page-break-after:always」属性は、要素が通常レンダリングされる位置の直後に、PDFページ内で強制的に改ページを行います。
- CSSでドキュメントの余白を設定する際は、次のように「in」を単位として使用できることをお忘れなく:margin: 1in;
- ページ区切りで分割したくない大きな div やその他の要素がある場合は、スタイル要素として「page-break-inside: avoid;」を使用してください。レンダリング時に分割を回避できる場合、その要素が分割されないよう処理されます。
- 文書内の内部リンクは、PDFでも維持されます。
PDFファイルの結合
概して、PDFマージドキュメントの動作は、
HTML版と非常に似ています。ただし、HTMLドキュメントを返す代わりに、HTML
テンプレートがPDFとしてレンダリングされます。上記の「Lava To PDF」ブロックの
設定のほとんどは、マージドキュメントでもサポートされています。これらのパラメータを制御する
ブロック設定がないため、代わりにテンプレートのHTMLタグ内に
パラメータとして追加する必要があります。 以下に、いくつかの設定(緑色で表示)の使用例を
簡単に示します。設定の完全な一覧は、その下に記載されています。
<html
document-width="11"
document-height="8.5"
document-name="mydocument.pdf"
autogenerate-bookmarks="true"
table-header-repeat-enabled="true"
avoid-image-breaks="true"
document-background-color="#c4c4c4;"
image-scaling-enabled="false"
reset-page-numbers-per-row="true" >
<body>
<header height="2" spacing=".1" background-color="#c80505">
This is the header. Current Person = {{ CurrentPerson.FullName }}
</header>
{{ CurrentPerson.Full Name }}
{% for row in Rows %}
<pre>{{ row.FullName }}</pre>
{% endfor %}
<footer height=".5" spacing="2" >
This is the footer. Current Person = {{ CurrentPerson.FullName }}
<br>
[page] of [topage];
</footer>
</body>
</html>
| 設定 | デフォルト | 注記 |
| ドキュメントの幅 | 8.5 | この機能については、説明して皆さんの知性を侮るようなことはしません。ただ、単位はインチで、小数も入力できるということだけ知っておいてください。 |
| document-height | 11 | 君ならできるよ… |
| ページ上部余白 | 1 | ページの上端。 |
| page-margin-bottom | 1 | えーと…そうですね、ページの下余白ですね。 |
| ドキュメント名 | document.pdf | これは、ユーザーがファイルをダウンロードした際のファイル名になります。Lava形式も対応しているため、「contribution-report.pdf」という名前を使う必要はなく、「contributions-ted-decker-2017.pdf」といった名前を付けることができます。 |
| レンダリング遅延 | 0 | これは、PDFのレンダリングを開始する前に待機する遅延時間(秒単位、小数点以下なし)を設定します。外部フォントのダウンロードやスクリプトの実行を待つ必要がある場合(Googleマップの読み込みなど)に役立ちます。 |
| ブックマークの自動生成 | false | これにより、HTML内のh1~h6タグからPDFのブックマークが作成されます。 |
You can add page headers and
footers. To do this add <header> and <footer> tags to your document
(as shown in blue in the example). These will be treated as page headers and
footers (meaning they will show on each page).
ヘッダーとフッターにも
設定があります。
| 設定 | 注記 |
| 高さ | これは、ヘッダーとフッターの高さ(インチ単位)です。 |
| スペース | これは、ヘッダー/フッターと文書本文との間の余白の高さ(インチ単位)です。 |
「Lava」コマンドについてはどうでしょうか?
すべてのスタッフユーザーは
独自のマージドキュメントをアップロードできるため、個々のマージドキュメントに対する
特定のLavaコマンドへのアクセスを安全に制御する方法はありません。Coreの
HTMLマージテンプレートと同様に、これらのテンプレートでは、有効なLavaコマンドを取得するために、
グローバル属性「Default Enabled Lava Commands」に依存しています。
「Lava to PDF」ワークフローアクション
最も単純な形では、このワークフローアクションは Lava HTML
テンプレートを受け取り、それを PDF ファイルに変換し、選択したワークフロー
属性に挿入します。この結果属性を使用するには、その型が「File」である必要があります。
以下に、テンプレートの非常に簡単な例と、
それによって生成されたPDFを示します。
まずは結果から(これを見た方がずっと楽しいですよね :) )

さて、前置きはこれくらいにして、これを
作成するために使用されたテンプレートをご紹介します。

- ファイル名:PDFに使用されるファイル名は、自由に設定できます。このフィールドには「Lava」といった文字列も入力可能なので、自分好みにカスタマイズできます。
- 結果属性:これは、PDFが保存されるファイル属性です。
- Lavaテンプレート:最後に、コンテンツや書式を決定するために使用されるHTMLテンプレートです。次に、その機能のいくつかについて詳しく見ていきます。
さて、例を見てみましたが、うわぁ…すごくかっこいい!でも…もっと
うまくできるはず…ですよね?HTMLとLavaの力を活用すれば、デザインを思う存分
自由に表現できます。このテンプレートとその仕上がりをぜひご覧ください。

さて、この芸術作品を生み出すテンプレートをご紹介します。

- 話を先に進める前に、ワークフローの「person」属性を変数に代入しておきましょう。そうすれば、後でそのプロパティや属性を参照できるようになります。属性の読み込み時に「Object」パラメータを使用している点にご注目ください。これにより、personオブジェクト全体を取得できます(デフォルトでは、単に名前だけが返されるフォーマット済みの値しか得られません。つまらないですね)。
- PDFにカスタムフォントを埋め込むことができる点にご注意ください。ただし、フォントを参照する前に、CSS内でフォントファイルを指定する必要があります。CSSでのカスタムフォントの読み込みに慣れている方ならお気づきでしょうが、otfまたはttfファイルを登録するだけで済みます。CSSのその数行下を見ると、この新しいフォントをbody要素に割り当てていることがわかります。
- テンプレート内で画像を簡単に参照できます。画像へのリンクにサーバー名が指定されていない点にご注目ください。HTML/CSS のベース URL は、「グローバル属性」で定義されたアプリケーションの内部ルートに基づいています。もちろん、ご希望であれば、リンクに完全なパスを指定しても構いません。
- 次に、ドキュメントに別の画像を追加します。今回は、personオブジェクト(PhotoUrl)からその画像を参照します。また、さまざまなCSSを使って画像をカスタマイズできる点にも注目してください。今回は、ちょっと遊び心で、画像を丸く見せて枠線を追加してみました!
- 最後に、ワークフローのいくつかの属性をご紹介します。
使用方法のレシピ
さて、作成できるドキュメントの種類については見てきましたので、次は
その活用例について考えてみましょう。
ドキュメントがワークフロー属性に保存されると、
そのドキュメントに対して実行できる操作にはいくつかの選択肢があります。以下の例を参考にしてください:
- 人物属性:「人物属性セット」アクションを使用すると、PDFをワークフロー属性から人物属性へ簡単に移動させることができます。
- グループメンバー属性:同様に、「グループメンバー属性セット」アクションを使用して、PDFをグループメンバー属性に移動することもできます。
- ファイルのメール送信:「メールを送信」アクション内で、以下のLavaを使用してファイルへのリンクをメールに含めることができます。
<a href="{{ 'Global' | Attribute:'ExternalApplicationRoot' }}GetFile.ashx?guid={{ Workflow | Attribute:'File','RawValue' }}">Download Receipt</a>
(注:属性キー(緑色で示されている部分)は、ご自身の値に合わせて更新する必要があります)
注意点とヒント
このワークフローアクションを使用してPDFを作成するのは、非常に
強力な機能です。ただし、これらのファイルはRock内で
バイナリファイルとして保存される点に注意が必要です。ファイルを格納する属性を設定する際は、
適切な場所に保存される「ファイルタイプ」を選択するように
してください。通常、データベースには保存されません。
データベースの保存にはコストがかかり、大規模なデータベースの
バックアップは困難な場合があります。その代わりに、ファイルを
サーバーのファイルシステムに保存することを検討してもよいでしょう。
特に、ファイルの
HTML/CSS を開発する際には、この点を考慮しておく必要があります。もしあなたがその道の達人(あるいはスタイルに対する基準が低い)でない限り、
ファイルを理想的な見た目に仕上げるには、おそらく何度か試行錯誤が必要になるでしょう。そんなファイルをすべてデータベースに保存するのは
避けたいところですよね(うっ!)。
また、このファイルに使用されるストレージプロバイダーは、
PDFが最初に保存されたワークフロー属性の「ファイルタイプ」で
設定されたものになる点にご注意ください。このワークフロー属性を個人
またはグループメンバーの属性に移動しても、元のバイナリファイル自体は移動せず、
そのファイルへのリンクのみが移動します。ワークフロー属性を設定する際は、
適切な「ファイルタイプ」を選択するようにしてください。
テンプレートにヘッダーやフッターを追加することができます。各
ツールキットのツールによって実装方法が若干異なるため、各ツールが
ヘッダー/フッターテンプレートをどのように実装しているかについては、上記の説明を必ずお読みください。テンプレート自体は
標準的なものです。
Each template is a snippet of HTML (do not add <html>,
<head> or <body> tags). These snippets stand-alone from the primary
content template, so you’ll need to re-implement any styling you’d like. These
templates do support Lava so feel free to use it. They also support other
dynamic arguments to support features like page numbering. Let’s look at that
next.
セクション引数
ヘッダーやフッターに以下の引数を追加することで、
ページ番号などの動的な機能を追加することができます。
- [page] - 現在印刷中のページ番号に置き換えられます
- [frompage] - 印刷する最初のページ番号に置き換えられます
- [topage] - 印刷する最後のページ番号に置き換えられます
- [webpage] - 印刷対象のページのURLに置き換えられます
- [section] - 現在のセクション名に置き換えられます
- [小見出し] - 現在の小見出し名に置き換えられます
- [date] - システムの設定されたローカル形式の今日の日付に置き換えられます
- [isodate] - ISO 8601拡張形式の現在の日付に置き換えられます
- [time] - システムのローカル形式による現在の時刻に置き換えられます
- [title] - 現在のページオブジェクトのタイトルに置き換えられます
- [doctitle] - 出力ドキュメントのタイトルに置き換えられます
- [sitepage] - 変換中の現在のサイト内のページ番号に置き換えられます
- [sitepages] - 変換中の現在のサイトに含まれるページ数に置き換えられます
ヘッダーやフッターがページの余白やコンテンツとどのように連携するかは、
最初は少し分かりにくいかもしれません。下の図は、基本的なレイアウトを示しています。

ヘッダーとフッターの余白設定は、厳密な科学というわけではありません。
例えば、ヘッダーの高さに十分なスペースを確保していないと、ヘッダーが
上部の余白からスペースを奪い始めます。余白が
なくなると、ヘッダーはページからはみ出して切り取られてしまいます。同様に、
コンテンツと重ならないように、ヘッダーやフッターの余白を
調整する必要があります。 ヘッダーやフッターがコンテンツと重なり始めた場合は、単に余白を増やしてください。
バージョン 1.0 からの更新
ライブラリをバージョン 2.0 に更新する際、
PDF ライブラリを変更する必要がありました。これは主に、Azure App Services 上で Rock を実行しているユーザーを
サポートするために行われました。新しいライブラリは以前のものよりもはるかに高速で、
システムリソースの消費も少なくなっています。つまり、誰にとってもメリットがあるのです。
最大の変更点は、ヘッダーとフッターの
動作に関するものです。詳細については、「ヘッダーとフッター」のセクションをご覧ください。
Lava to PDF の、現在は存在しないブロック設定
新しいPDFライブラリは、旧ライブラリの
すべての設定に対応しているわけではありません。以下に、対応されなかった設定の一部を挙げます。ほとんどの場合、
同じ結果を得るための有効な回避策があります。概して、
失うものはそれほど多くなく、得られるメリットの方が大きいでしょう。
| ページモード | これは、ファイルが最初に読み込まれた際に、ブックマークやサムネイルを表示するかどうかを決定するために使用されていました。 |
| 表見出しの繰り返し | This feature is also not in the new library, but can be achieved through normal CSS print styling. Be sure to put your headings inside of a <thead> tag to ensure they are repeated on each page (this is proper way to markup headings on a table).Example:<table> <thead> <th> <td>Col Heading 1</td> <td>Col Heading 2</td> <td>Col Heading 3</td> </th> </thead></table>
|
| 画像による改ページを避ける | この機能は、通常のCSSプリントスタイルシートの一部でもあります。 img { page-break-inside: avoid; } |
| 文書の背景色 | この設定は、以前はPDFページの背景色を変更するために使用されていました。現在でもコンテンツの背景色は変更できますが、ページ全体の色を変更することはできません。そもそも、グラフィックデザインの観点から言えば、これはあまり良い方法とは言えません。 |
| 画像の拡大縮小が有効になっています | 以前は、PDFへの組み込み時に画像のサイズを自動的に調整し、スペースを節約していました。 |
新しいレンダリングエンジンは、v1.0
バージョンとは少し異なります。例えば、Bootstrapのカラムを使用する際は、一般的な -md- ではなく、
-xs- ブレークポイントを使用するようにしてください。
正しい表記:
col-xs-6
誤った表記:
col-md-6
さあ、出撃だ、兵士よ
もう話はこれくらいにして、さあ外へ出て、
この新たな武器を武器庫に加え、宣教活動を推進しましょう!
でも、その前に……もうひとつお楽しみを。以下に、寄付明細書用のシンプルなLava
テンプレートを掲載します。実際にはあくまで出発点のようなものですが、
必要な基本情報はすべて含まれています。
{% assign currentYear = 'Now' | Date:'yyyy' %}
{% assign selectedYear = currentYear %}
{% assign queryParms = 'Global' | Page:'QueryString' %}
{% for item in queryParms %}
{% assign kvItem = item | PropertyToKeyValue %}
{% if kvItem.Key == 'Year' %}
{% assign selectedYear = kvItem.Value %}
{% endif %}
{% endfor %}
{% assign startDate = '1/1/' | Append:selectedYear %}
{% assign endDate = '12/31/' | Append:selectedYear %}
{% if currentYear == selectedYear %}
{% assign endDate = 'Now' | Date:'M/d/yyyy' %}
{% endif %}
<html>
<head>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
padding: .5in;
}
table tr td,
table tr th {
page-break-inside: avoid;
}
</style>
<!-- Note: You may need to edit this URL to match your environment -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="row">
<div class="col-md-6">
<strong>{{ 'Global' | Attribute:'OrganizationName' }}</strong><br />
{{ 'Global' | Attribute:'OrganizationAddress' }}<br />
{{ 'Global' | Attribute:'OrganizationWebsite' }}
</div>
<div class="col-md-6 text-right">
<h4>Charitable Contributions for the Year {{ selectedYear }}</h4>
<p>{{ startDate }} - {{ endDate }}<p>
</div>
</div>
<h4 style="margin-bottom: 24px;">
{{ CurrentPerson.FirstName }} {{ CurrentPerson.LastName }}<br />
{{ CurrentPerson | Address:'Mailing','[[Street1]]' }}<br />
{% assign address2 = CurrentPerson | Address:'Mailing','[[Street2]]' %}
{% if address2 != '' %}
{{ address2 }} <br />
{% endif %}
{{ CurrentPerson | Address:'Mailing','[[City]], [[State]] [[PostalCode]]' }}
</h4>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Giving Area</th>
<th>Check/Trans #</th>
<th style="text-align: right;">Amount</th>
</tr>
</thead>
{% sql %}
SELECT
t.[TransactionDateTime],
a.[PublicName],
t.[TransactionCode],
d.[Amount]
FROM
[FinancialTransactionDetail] d
INNER JOIN [FinancialTransaction] t ON t.[Id] = d.[TransactionId]
INNER JOIN [PersonAlias] pa ON pa.[Id] = t.[AuthorizedPersonAliasId]
INNER JOIN [Person] p ON p.[Id] = pa.[PersonId]
INNER JOIN [FinancialAccount] a ON a.[Id] = d.[AccountId]
WHERE
p.[GivingId] = '{{ CurrentPerson.GivingId }}'
AND DATEPART( yyyy, t.[TransactionDateTime]) = {{ selectedYear }}
{% endsql %}
{% for transactionDetail in results %}
{{ transaction.Id }}
<tr>
<td>{{ transactionDetail.TransactionDateTime | Date:'M/d/yyy' }}</td>
<td>{{ transactionDetail.PublicName }}</td>
<td>{{ transactionDetail.TransactionCode }}</td>
<td style="text-align: right;">{{ 'Global' | Attribute:'CurrencySymbol' }}{{ transactionDetail.Amount }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>