2017.05.24

Visualforceの帳票出力を極める

  • このエントリーをはてなブックマークに追加
  • follow us in feedly
皆様、GWはいかがお過ごしでしたでしょうか?ゆっくりできた方、そうでなかった方いるかと思いますが気持ちを切り替えてがんばりましょう! 今回のブログですが、皆さんSalesforce(Visualforce)で帳票を作成する場合いろいろ制限もありお困りかと思います。GW中時間もあったのでSalesforce(Visualforce)でどうやって帳票(PDF化)に立ち向かったらよいのかについて調べてみました。いろいろできることもわかりましたので、皆様に共有できたらと思います。
ただし、ご理解いただきたいのは2017年5月11日現在の情報でありSalesforceのPDF化の仕様が変更された場合は、表示が崩れてしまったり、表示される内容が変わってしまう可能性があります。参考にされる場合、保証は出来ませんのでご理解ご了承ください。

VisualforceでのPDF化の課題と解決方法

日本語を表示する

割りとはまってしまうVisualforceでPDFを作成するとき日本語が表示されない件についておさらいしましょう!新規でVisualforceページを作成し、手書きか、コピペなどして試してみてください。
<apex:page renderas="pdf">
     
        <style>
            body { font-family: Arial Unicode MS; }
        </style>
     
     
        VisualforceのPDFで日本語表示!
     
</apex:page>
【日本語が表示されないサンプル】
※きれいに日本語だけ表示されません。(T_T)

出力結果:VisualforcePDF

<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
     
        <style>
            body { font-family: Arial Unicode MS; }
        </style>
     
     
        VisualforceのPDFで日本語表示!
     
</apex:page>
【日本語が表示されるサンプル】

出力結果:VisualforceのPDFで日本語表示!

※やっと日本語が表示されました。(^o^)/

POINT.1 [apex:pege]タグの3つの属性の指定

<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
</apex:page>
POINT.1 [apex:pege]タグの3つの属性の指定
「renderAs="pdf"」・・・pdfとして出力
「applyHtmlTag="false"」・・・生成されるHTML出力に、 タグをVisualforceで自動的に追加するかどうか
「showHeader="false"」・・・ページにSalesforceタブのヘッダーを含めるかどうか
これらはおまじないだと思って手書きでPDF化する際に指定するようにしましょう

POINT.2 CSSで日本語用のフォントを指定する

<style>
    body { font-family: Arial Unicode MS; }
</style>
POINT.2 CSSで日本語用のフォントを指定する
残念ながら日本語を表示できるフォントは「Arial Unicode MS」のみになります。ここまで日本語表示についておさらいしました。

ページ(用紙)の設定

用紙のサイズ・向きについては、styleタグの中で「 @page { } 」の中に指定します。
<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
     
        <style>
            body { font-family: Arial Unicode MS; } /* 日本語フォント指定 */
            @page {
                size: A4 landscape; /* A4 横置き */
                margin: 10mm; /* 上下左右の余白10mm */
            }
        </style>
     
     
        <p>VisualforceのPDFで日本語表示!</p>
     
</apex:page>
【用紙のサイズ・向きの指定サンプル】
@page { size: A4 } A4
@page { size: A4 landscape } A4 横置き
@page { size: A4; margin: 10mm; } A4 余白10mm
@page { size: 210mm 297mm } 用紙のサイズをmmで指定する これはA4の縦置きになります。
といった設定が出来ます。

【補足】CSS設定の有効・無効について

印刷用のCSSとして、@media print { } または、@media all { } で囲んでその他のCSSを指定した場合にはPDF化の際に有効になります。 逆に、「@media screen { } ・・・ディスプレイ用」・「@media projection { } ・・・プロジェクター用」 これらで囲んで指定しますとPDF化の際には無効になります。
それではこれまで説明した部分をまとめてみましょう。
<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
     
        <style>
            body { font-family: Arial Unicode MS; } /* 日本語フォント指定 */
            @page {
            size: A4 landscape; /* A4 横置き */
            margin: 10mm;
            }
            @media print { /* 印刷用 */
                p {
                    color:#f00; /* 文字色赤 */
                    font-size:3em;
                }
            }
            @media screen { /* ディスプレイ用 */
                p {
                    color:#000; /* 文字色黒 */
                    font-size:5em;
                }
            }
        </style>
     
     
        <p>VisualforceのPDFで日本語表示!</p>
     
</apex:page>
【CSS設定の有効・無効についてのサンプル】
この出力では A4の用紙を横置きで余白は10mmで設定され、表示される文字はCSSでは基本後から記述してある「@media screen」が有効になりそうなものですが、こちらは無視され 「@media print」で指定された文字色が赤色の文字サイズは3emになります。

改ページについて

改ページについてですが、対象の手前で改ページしたい場合、対象の後で改ページしたい場合とあるかと思います。
※Pタグで囲われた部分はHTMLでは段落という扱いになります、ここでは段落の直前・直後で改ページする方法について説明します。
cssで指定する場合の書き方です。
例)段落の直前で改ページしたい場合
p { page-break-before: always; }
例)段落の直後で改ページしたい場合
p { page-break-after: always; }
<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
     
        <style>
            body { font-family: Arial Unicode MS; } /* 日本語フォント指定 */
            @page {
              size: A4 landscape; /* A4 横置き */
              margin: 10mm;
            }
            .pagebreak {
                page-break-before: always;
            }
            p {
                font-size:2em;
                color:#f00;
            }
        </style>
     
     
        <p>改ページのテスト1ページ目</p>
        <p class="pagebreak">改ページのテスト2ページ目</p>
        <p class="pagebreak">改ページのテスト3ページ目</p>
     
</apex:page>
【段落前改ページのサンプル】
今回の例では、Pタグに改ページしたいものには「class="pagebreak" 」をつけました。CSS側で「page-break-before: always;」つまりPタグの直前で改ページをいれました。

ヘッダー・フッターに表示しよう

改ページができたら、ヘッダーやフッターになにか印刷したくなるかと思います。ここではヘッダー・フッターの指定の仕方を説明したいと思います。
ヘッダーの左に(会社名)、フッターの中央に(ページ番号/総ページ数)を印刷できるようにします。
<apex:page renderas="pdf" applyhtmltag="false" showheader="false">
     
        <style type="text/css">
            body { font-family: Arial Unicode MS; }
            @page {
                size: A4 landscape; /* A4 横置き */
                margin: 10mm;
                @top-left{
                    font-family: Arial Unicode MS;
                    content: "株式会社 テラスカイ";
                }
                @bottom-center {
                    content: "Page: " counter(page) " / " counter(pages);
                }
            }
            p {
                font-size:3em;
            }
        </style>
     
     
        <p>ヘッダーとフッター表示サンプル</p>
     
</apex:page>
ヘッダー・フッターに表示しよう
CSSの記述方法の解説です。@page{}の中に入れ子にして記述する必要があります。 @page{}の中に@top-left(上の左に表示)といった感じです。 表示するものですが、文字の場合で日本語の場合「font-family: Arial Unicode MS;」これは必要です。次に「content:」の後に【'表示したい文字'】とします。 ページ番号ですが「content:」の後に「counter(page);」で現在のページが取得でき表示してくれます。 さらに総ページ数ですが「content:」の後に「counter(pages);」とすることで取得することができます。

以下はそれぞれ表示するときの場所の参考にしてください。
@top-left-corner @top-left @top-center @top-right @top-right-corner
@left-top Page Area
ここには表示できません!
@right-top
@left-middle @right-middle
@left-bottom @right-bottom
@bottom-left-corner @bottom-left @bottom-center @bottom-right @bottom-right-corner

透かしを追加する

ここでは印刷するときの透かしを入れる方法を紹介します。例えば社外秘ですとか、社外持出禁止などのような決まった文字であれば画像でも良いのですが、 印刷した日付や印刷した人などの動的情報を取得して透かしに入れる方法です。
<style type="text/css">
    @page {
        size: A4 landscape; /* A4 横置き */
        margin: 10mm;
        @top-center {
            font-family: Arial Unicode MS; /* 日本語表示用に必須 */
            content: "社外持出禁止 \A 出力日:{!record.LastModifiedDate} \A 出力者:{!$User.LastName} {!$User.FirstName}";
            white-space: pre;
            font-size:2em;
            font-weight:bold;
            color:#ccc;
            padding-top:300px;
        }
    }
</style>
透かしを追加する

ポイントは「@top-center」に文字を記述しているのですが、padding-top:300px;で表示位置を縦の中心のほうへずらしています(この方法しか自分では動きませんでした) また、「社外持出禁止」と「出力日」、「出力者」の間の改行ですが、「\A」とその下「white-space: pre;」のセットで改行できます。 動的なデータの取得ですが「出力者」はログインしているユーザの情報から持ってきましたので、 { ! $User.LastName } { ! $User.FirstName }。Visualforceのグローバルの情報から取得します。 出力日ですが、レコードの最終更新日を取得するようにしました。 ※ SkyVisualEditorでレコードの最終更新日を取得する場合の記述の仕方:{!record.LastModifiedDate}

SkyVisualEditorでの解決方法

ページ設定

SkyVisualEditorからPDFのページ設定をする場合、PDF化のチェックをし、用紙のサイズ、用紙の向き、余白をプロパティで簡単に設定できます。

CSSの記述場所について

VisualforceでのPDF化の課題と解決方法で紹介したヘッダー・フッターについての記述や、PDF化時に有効なCSS、無効なCSSについてもSkyVisualEditorでは、ページのプロパティからページスタイルを開きダイアログ内で 記述していただくことで指定できます。

改ページについて

SkyVisualEditorご利用の場合は「SkyVisualEditor標準AppComponent」の中にPDF改ページというAppComponentがありますのでそちらを配置するだけです。
※ page-break-before: always; が出力されるので配置したAppComponentの直前で改ページされます。

明細行が多い時に明細を分けて表示する

ここでは、SkyVisualEditorをつかった高度なPDFページの作成方法を紹介します。 例えば、明細行が多い場合に1~10行目までは1ページ目に、11~20行目間は2ページ目に表示したいといった場合をSkyVisualEditorを利用して作成してみます。

(1)Salesforceレイアウトでパネルグリッドを利用してレイアウトを作成

まず、SkyVisualEditorでPDF用のページを作成します。このとき1枚の帳票でしたら自由レイアウトを選択し、背景画像の上に表示させたい項目や明細行用のテーブルを配置して 作成すると思いますが、今回のように改ページをしたい場合や、明細行を2ページに分ける場合には、Salesforceレイアウトを使用します。 以下のように、パネルグリッドを駆使してレイアウトを作成していきます。

※上の図ではパネルグリッドの罫線を表示していますが、最後にプロパティの設定で罫線を非表示にします。

(2)パネルグリッドを下に配置し、その中に同じ内容のデータテーブルを配置します。

(3)上に配置してあるデータテーブルのプロパティを変更する

データテーブルのプロパティで設定をしていきます。プロパティの一番上「ID:estimateTable1」としておきます。 次に、表示順を昇順に設定する必要があります。【高度なテーブル機能】の【絞込条件】の編集ダイアログを開きます。 ※ソート条件で「項目:No」、「並び順:昇順」、「Null値の位置:終端」としておきます。
今回作成するものは1ページに10行のデータを表示するようにしたいと思いますので「表示上限:10」に設定します。

(4)2ページ目のデータテーブルの設定

同様に2ページ目のデータテーブルのプロパティで設定をしていきます。
・「ID:estimateTable2」としておきます。
・ 表示順を昇順に設定します。「項目:No」、「並び順:昇順」、「Null値の位置:終端」
さらに検索条件で「項目:No」、「演算子:>」、「値:10」とします。
※ これで10行目以後を表示するデータテーブルになりました。

(5)改ページ設定(CSS)

改ページ設定をしていきます。次のページ用にデータテーブルを入れたパネルグリッドを配置しましたが、そのパネルグリッドに改ページの設定をしていきます。 対象のパネルグリッドのプロパティを表示するには、枠をダブルクリックすると表示しやすいです。プロパティの上部が「パネルグリッド・セル」ではなく、 「パネルグリッド」であることを確認してください。
プロパティの【高度な設定】の【表示条件】のダイアログを開き「{!estimateTable2.items.size > 0}」と入力します。 ※これはテーブルのIDとして設定したestimateTable2が、Apex側のリストにいくつレコードを持っているかを調べます。1レコードでもあればパネルグリッドを表示させます。

最後に【開発】の【スタイルクラス】のダイアログを開き「pages 」と入力します。
ページスタイルに以下を記述して置いてください。
.pages {
    page-break-before: always;  /* パネルグリッドの前で改ページ */
    padding-top: 1em;
    margin-top:3em;
}
/* ここからはおまけ */
@page {
    @bottom-center {
         /* Page footer */
        content: "Page " counter(page) " / " counter(pages);
    }
}
改ページ設定(CSS)
デプロイして確認してみましょう!

最後にまとめ

VisualforceのPDF化について、いろいろと調べて書いてみましたが、CSSを駆使することで出来ることもたくさんあるようです。 今回のブログでは長すぎましたのでこのあたりで終わりにしておこうと思いますが、もっと調べて今後も紹介できたらと思います。 「明細行が多い時に明細を分けて表示する」の部分ではSkyVisualEditorの操作に慣れている方向けに書きましたので、設定等省略している部分もありますのでうまくいかなかった場合は、 SkyVisualEditorのアドミンカフェに申し込みいただき問い合わせいただければと思います。
読んでいただきありがとうございました。

SkyVisualEditorアドミンカフェ
~自分のペースで好きなタイミングでアドバイスをもらえる。~

テラスカイのエンジニアに直接アドバイスを受けながら画面作成しませんか?
SkyVisualEditor/SuPICEトライアル中及びご導入済みのお客様にご参加いただける無料のイベントです。

↓↓↓ 参加申込みはこちらをクリック! ↓↓↓

アドミンカフェバナー

82 件

関連する記事