logo

サイト内検索
ココログ最強検索 by 暴想

最近のトラックバック

無料ブログはココログ

« 2011年7月 | トップページ | 2011年9月 »

2011年8月

VisualForcePDFの改ページについて_4:VisualForce編

Creating Professional PDF Documents with CSS and Visualforce
※基本的に上記リンクに描いてあることを噛み砕んでいる物です。

前回はラッパー利用のススメという形で作りの解説をしました。
今回はVisualForce作りについてのTipsを書いてみます。

VisualForce帳票の構成は概ね以下のようになっています。

 

<apex:page showHeader="false" renderAs="pdf" controller="コントローラー名">
<!-- 必ず <head>の中に<Style>を入れ子にする。最重要はFont指定のbodyと@pageの2指定 -->
    <head><style>
        <!-- フォント設定はこれしか指定できない。これ以外は文字化ける -->
        body { font-family: Arial Unicode MS; font-size:10.5pt}
        <!-- @pageで印刷時のサイズ決定。 -->
        @page { size: A4; }


        .recordtable {
            border-collapse: collapse;
            border-left:1px solid black;
            border-bottom:1px solid black;
        }
        .recordth{
            border-top   :1px solid black;
            border-right :1px solid black;
            <!-- 2pxにしないと二重線にならない -->
            border-bottom:2px double black;
        }
        .recordtd {
            border-right:1px solid black;
        }
       
        <!-- データレコードで利用するボーダーライン制御用CSS -->
        .topSolid {
            border-top:1px solid black;
        }
        .topDotted {
            border-top:1px dotted black;
        }
    </style></head>


    <apex:pageblock> <!-- 帳票の下地ボックス -->
        <apex:repeat value="{!(1ページデータ格納リスト)}" var="report">
            <div style="{!report.(page-break-after:always;設定)}">
               
                <!-- ページのヘッダを書く -->
               
                <!-- 実データ表示 -->
                <table class="recordtable">
                    <!-- レコード表示のヘッダー -->
                    <tr>
                        <td class="recordth" style="width:100px">データ1</td>
                        <td class="recordth" style="width:100px">データ2</td>
                        <td class="recordth" style="width:100px">データ3</td>
                    </tr>
                    <apex:repeat value="{!report.(1ページのデータリスト)}" var="record>
                        <tr>
                            <td class="recordtd {!record.LineStyle}">{!record.Data1}</td>
                            <td class="recordtd {!record.LineStyle}">{!record.record.Data2}</td>
                            <td class="recordtd {!record.LineStyle}">{!record.record.Data3}</td>
                        </tr>
                    </apex:repeat>
                </table>
               
                <!-- フッタを書く -->
               
            </div>
        </apex:repeat>
    </apex:pageblock>
</apex:page>


これだけでも良いのですが、いくつかカスタム出来るところがあります。


1.A4サイズのWidth設定
2.2ページ目以降の上部マージン処理
3.レコードのHeightを一定に保つ
4.CSSを外出しにする



 

1.A4サイズのWidth設定

PDF帳票をA4設定する場合、表示領域は概ね 750~760px になります。

しかし帳票利用を考えると印刷のファイリングを想定する必要があります。

パンチ穴の位置を考えると、左に40~50px程度のマージンを取ると調度良いようです。
マージンはpage-break-after:always;を設定するDivに対して行うと良いかと思います。

//page-break-after:always;設定Div
<div style="{!page.(page-break-after:always;設定})">
  ↓    ↓    ↓    ↓    ↓    ↓    ↓    ↓
<div style="{!page.page-break-after:always;設定} margin-left:50px;">

Tips:B4サイズだと、Width:1260程度が調度良いようです。
  サイズについては調整を重ねて調度良い分水嶺を探すのが良いかと思います。





===========================

2.2ページ目以降の上部マージン処理

例えば先程のDivに、Margin-Topを指定したとします。
しかしそれが適用されるのは1ページ目だけで、2ページ目からは何故か適用されません。

※理由は不明ですが、恐らく改ページに関するものだと思われます。
 隙間に吸われてしまっているのかも。

よって、ページトップのマージンは物理的にスペースを取る必要があります。

//1ページを表示するapex:repeatの部分
<apex:repeat value="{!(1ページデータ格納リスト)}" var="page">
    <div style="{!page.(page-break-after:always;設定}) margin-left:50px;">
        :
    </div>
</apex>
  ↓    ↓    ↓    ↓    ↓    ↓    ↓    ↓
<apex:repeat value="{!(1ページデータ格納リスト)}" var="page">
    <div style="height:8px" /> <!-- 状況に応じて再設定 -->
    <div style="{!page.(page-break-after:always;設定}) margin-left:50px;">
        :
    </div>
</apex>

つまり改ページ最初に必ず特定Heightのスパンができる・・・ということになります。



3.レコードのHeightを一定に保つ

実際のデータ表示部はTableなので、内容が全て空だと潰れてしまいます。
よって何らかの手段で一定量のHeightを取る必要があります。

取り方としては
 1.Divで予めHeightを指定してしまう。
 2.空の時は全角スペースを代替出力する。
などがありますが、ここでは後者のスペースで取るケースを考えます。

 

//1レコード表示部分
<td class="recordtd {!item.LineStyle}">{!items.Data1}</td>
  ↓    ↓    ↓    ↓    ↓    ↓    ↓    ↓
<td class="recordtd {!item.LineStyle}">
    {!items.Data1}
    <apex:outputText value="{!' '}" rendered="{!items.Data1 == ''}" />
</td>
※数式でのString表現で、全角スペースを指定

Tips:実はボーダーを表示非表示にするときに1px前後が累計して全体Heightが増えたり減ったりします。
  厳密にやる場合、白いBorder挿入も検討する必要があるかもしれません。





4.CSSを外出しにする

帳票を利用するとき、利用するCSSは全体でほぼ8~9割は同一の物になると思います。
よって、CSSを外出しにすることも検討しましょう。

方法は2パターン。
1.静的リソースにCSSファイルを置き、それを参照する。
2.compositionを利用する。

ここでは後者を推奨します。
前者の場合、内容を即座に見られない上に修正がナカナカ面倒です。
後者は実質VisualForceなので修正も参照も楽にできます。

※参照:apex:insert

//実装例:Page名「ReportCSS」
//ContentTypeはtext/cssにする。
<apex:page  contentType="text/css">
    .recordtable {
        border-collapse: collapse;
        border-left:1px solid black;
        border-bottom:1px solid black;
    }
    <apex:insert name="StyleSheet"/>
</apex:page>

//表出力用VisualForce <apex:page headshow="false" renderAs="pdf" controller="コントローラー名">     <head><style>         <apex:composition template="ReportCSS">             <apex:define name="StyleSheet" />         </apex:composition>         .追加CSS{}         .独自用にOverrideしたCSS{}     </style></head>     :     : </apex:page>

ただし上記のように構成する場合、renderAs="html"にしたときソースがプレーンテキスト化します。
HTMLにしたいときは、compositionをコメントアウトしてください。




-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
最後に今日までに解説したものから作る帳票の1例を作ってみました。
表としては極単純な、SalesForceユーザのリストを表示するものです。
(ただし内部的にダミーレコードを用意し、2ページ以上の表示ができるようにしています)
ソースは「こちら」です。
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

では良きSalesForceライフを。

<08/03追記> PDF表示VisualForceの apex:page タグに「 contentType="text/html" 」を指定すると、 renderAs = html にしてもHTMLで表示されるようになります。 この修正は既にサンプルソースに適用済みです。

« 2011年7月 | トップページ | 2011年9月 »