function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
moxxmoxx 

PDF出力時に特定行数で改ページする方法

Visualforceで「renderAs="pdf"」を使用してpdf出力する際、
特定の行数で改ページする方法を検討しています。

検討用のサンプルとして以下のようなVisualforceページを作成したのですが、
出力されたpdfは、改ページはできているものの、
どのページにも最終ページ分のデータが表示されてしまいました。

どのようにすれば、ページごとに適切なデータが表示されるでしょうか?

もしくは、他に適切な改ページ方法がありますでしょうか?


ご教示いただければ幸いに存じます。

 

【Visualforce】

<apex:page standardController="Account" extensions="ExtensionController" showHeader="false" sidebar="false" renderAs="pdf">
  <body style="font-family: Arial Unicode MS;">
    <apex:repeat value="{!printRecords}" var="items" id="thePage">
      <apex:repeat value="{!items}" var="item" id="theTable">
        <apex:outputtext value="{!item.Name}"/>
        <br />
      </apex:repeat>
      <div style="page-break-after: always;"/>
    </apex:repeat>
  </body>
</apex:page>

 

【コントローラ】

public class ExtensionController {

    private final Account AccountObj;
    private static Integer pageSize = 5;

    public List<Contact[]> printRecords {get; private set;}

    public ExtensionController(ApexPages.StandardController controller) {
        this.AccountObj = (Account)controller.getRecord();
        BindData();
    }

    private void BindData(){
        String nowId = AccountObj.Id;
        Contact[] Contacts = 
            [SELECT id, Name
               FROM Contact 
              WHERE AccountId = :nowId 
              ORDER BY Name];

        printRecords = new List<Contact[]>();

        Contact[] pageContacts = new Contact[]{};
        Integer counter = 0;
         
        for(Contact c : Contacts){
            if (counter <= pageSize){
                pageContacts.add(c);
                counter++;
            }
            if (counter == pageSize){
                counter = 0;
                printRecords.add(pageContacts);
                pageContacts.clear();
            }
        }
        if(!pageContacts.isEmpty()){
            printRecords.add(pageContacts);
        }
    }
}

 



 

Best Answer chosen by Admin (Salesforce Developers) 
matsumatsu

書き方が不親切でしたね。

 

Apexの

pageContacts.clear();

の部分を

 

pageContacts = new Contact[]{};

 

と変更するだけで、

visualforvuceは何も変更しなくても、思い通りの結果が得られると思いますよ。

 

配列は、これを参照してくださいねーと設定しているだけなので、

pageContacts.clear();だと、結局最後のが全部に表示されてしまうんですよね。

 

例えば、

  箱1.add(みかん);

  棚1.add(箱1);

  箱1.clear();//箱1の中身を空にする。

  箱1.add(りんご);

ってしちゃうと、棚1に入れておいた箱1の中身までりんごに変わってしまうんです。

ですので、

  箱1.add(みかん);

  棚1.add(箱1);

  箱1 = new 箱;//新しい箱を作る。

  箱1.add(りんご);

ってして、同じ箱1っていう名前でも、違う箱1を用意してあげる必要があります。

 

repeatが問題というより、repeatをするための配列の作り方の問題です。

All Answers

yyuummaayyuummaa

改ページするには用紙サイズを指定し、1ページ分の高さを指定して上げる必要があります。

要するに改ページという概念はありません。1ページにおさまらない場合は勝手に2ページ目にいきます。

matsumatsu
pageContacts.clear();

の部分が問題ですね。

 

pageContacts = new Contact[]{};

 

のように、一回一回作り直せば、思い通りに出力できると思いますよ。

 

 

 

 

 

yyuummaayyuummaa

pageContacts = new Contact[]{};

でrepeatすると1ページ目、2ページ目となるのでしょうか?

matsumatsu

書き方が不親切でしたね。

 

Apexの

pageContacts.clear();

の部分を

 

pageContacts = new Contact[]{};

 

と変更するだけで、

visualforvuceは何も変更しなくても、思い通りの結果が得られると思いますよ。

 

配列は、これを参照してくださいねーと設定しているだけなので、

pageContacts.clear();だと、結局最後のが全部に表示されてしまうんですよね。

 

例えば、

  箱1.add(みかん);

  棚1.add(箱1);

  箱1.clear();//箱1の中身を空にする。

  箱1.add(りんご);

ってしちゃうと、棚1に入れておいた箱1の中身までりんごに変わってしまうんです。

ですので、

  箱1.add(みかん);

  棚1.add(箱1);

  箱1 = new 箱;//新しい箱を作る。

  箱1.add(りんご);

ってして、同じ箱1っていう名前でも、違う箱1を用意してあげる必要があります。

 

repeatが問題というより、repeatをするための配列の作り方の問題です。

This was selected as the best answer
yyuummaayyuummaa

私の方も認識違いがありました。

こちらの元質問はmatsuさんの回答内容を求めていますね。

 

私自身が聞きたかったことは

1ページ目、2ページ目の制御を簡単にできる方法があるのかなと。

過去案件でPDFを扱った時にrepeatのレコード数が多い場合に2ページ目に自動で突き抜けてしまう状況があったので。

簡単に50レコード目以降は2ページ目に表示するとかあればいいんですけどね。

matsumatsu

わ、申し訳ない。

投稿された方のお名前をきちんと拝見せずに投稿してしまいました。

私の回答は、元の質問への解決方法ですね。

 

> 1ページ目、2ページ目の制御を簡単にできる方法があるのかなと。

 

私もこれに関しては、思いつかずに悪戦苦闘しています。

50レコードごとにフラグをつけて、ついていたら改ページ(rendered制御)とか、

今回のように、リストを分けてしまうとか。

何か簡単な方法があれば良いですね。

私も知りたいです。

moxxmoxx

ご回答ありがとうございます。

ご教示いただいたとおり、

pageContacts.clear();

の部分を、

pageContacts = new Contact[]{};

 と変更することで、ページごとに適切なデータが表示されました。


簡単な方法ではないですが、
他の方法が見つかるまでは、この方法で改ページを実装することにします。

ありがとうございました。

 

matsumatsu

> yyuummaa様

 

ちょっとそれでもすれ違っている気がしたので、念のため。

改ページという概念自体は存在します。

質問された方が書かれている、

 

<div style="page-break-after: always;"/>

の部分が、改ページを指示する部分です。