この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Apex からの PDF としての Visualforce ページの表示

Apex で PageReference.getContentAsPDF() メソッドを使用して、Visualforce ページを PDF データとして表示できます。次に、Apex コードを使用して、その PDF データをメールの添付ファイル、ドキュメント、Chatter 投稿などに変換します。
次の例は、取引先とレポート形式を選択して、生成されたレポートを指定されたメールアドレスに送信する 3 つの簡単な要素フォームです。
1<apex:page title="Account Summary" tabStyle="Account"
2    controller="PdfEmailerController">
3
4    <apex:pageMessages />
5
6    <apex:form >
7        <apex:pageBlock title="Account Summary">
8    
9        <p>Select a recently modified account to summarize.</p>
10        <p/>
11        
12        <apex:pageBlockSection title="Report Format">
13        
14            <!-- Select account menu -->
15            <apex:pageBlockSectionItem>
16                <apex:outputLabel for="selectedAccount" value="Account"/> 
17                <apex:selectList id="selectedAccount" value="{! selectedAccount }" 
18                                 size="1">
19                    <apex:selectOption /> <!-- blank by default -->
20                    <apex:selectOptions value="{! recentAccounts }" />
21                </apex:selectList>
22            </apex:pageBlockSectionItem>
23
24            <!-- Select report format menu -->
25            <apex:pageBlockSectionItem >
26                <apex:outputLabel for="selectedReport" value="Summary Format"/> 
27                <apex:selectList id="selectedReport" value="{! selectedReport }" 
28                                 size="1">
29                    <apex:selectOptions value="{! reportFormats }" />
30                </apex:selectList>
31            </apex:pageBlockSectionItem>
32
33            <!-- Email recipient input field -->
34            <apex:pageBlockSectionItem >
35                <apex:outputLabel for="recipientEmail" value="Send To"/> 
36                <apex:inputText value="{! recipientEmail }" size="40"/>
37            </apex:pageBlockSectionItem>
38
39        </apex:pageBlockSection>
40            
41        <apex:pageBlockButtons location="bottom">
42            <apex:commandButton action="{! sendReport }" value="Send Account Summary" />
43        </apex:pageBlockButtons>
44    
45    </apex:pageBlock>
46    </apex:form>
47
48</apex:page>

このページは、シンプルなユーザインターフェースです。Apex から PDF ファイルを生成する場合、すべてのアクションは Apex コード内にあります。

この例では、ページのコントローラとして指定された PdfEmailerController クラスにそのコードがあります。
1public with sharing class PdfEmailerController {
2    
3    // Form fields
4    public Id selectedAccount    { get; set; }  // Account selected on Visualforce page
5    public String selectedReport { get; set; }  // Report selected
6    public String recipientEmail { get; set; }  // Send to this email
7    
8    // Action method for the [Send Account Summary] button
9    public PageReference sendReport() {
10
11        // NOTE: Abbreviated error checking to keep the code sample short
12        //       You, of course, would never do this little error checking
13        if(String.isBlank(this.selectedAccount) || String.isBlank(this.recipientEmail)) {
14            ApexPages.addMessage(new 
15                ApexPages.Message(ApexPages.Severity.ERROR, 
16               'Errors on the form. Please correct and resubmit.'));
17            return null; // early out
18        }
19        
20        // Get account name for email message strings
21        Account account = [SELECT Name 
22                           FROM Account 
23                           WHERE Id = :this.selectedAccount 
24                           LIMIT 1];
25        if(null == account) {
26            // Got a bogus ID from the form submission
27            ApexPages.addMessage(new 
28                ApexPages.Message(ApexPages.Severity.ERROR, 
29               'Invalid account. Please correct and resubmit.'));
30            return null; // early out
31        }
32        
33        // Create email
34        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
35        message.setToAddresses(new String[]{ this.recipientEmail });
36        message.setSubject('Account summary for ' + account.Name);
37        message.setHtmlBody('Here\'s a summary for the ' + account.Name + ' account.');
38        
39        // Create PDF
40        PageReference reportPage = 
41            (PageReference)this.reportPagesIndex.get(this.selectedReport);
42        reportPage.getParameters().put('id', this.selectedAccount);
43        Blob reportPdf;
44        try {
45            reportPdf = reportPage.getContentAsPDF();
46        }
47        catch (Exception e) {
48            reportPdf = Blob.valueOf(e.getMessage());
49        }
50        
51        // Attach PDF to email and send
52        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
53        attachment.setContentType('application/pdf');
54        attachment.setFileName('AccountSummary-' + account.Name + '.pdf');
55        attachment.setInline(false);
56        attachment.setBody(reportPdf);
57        message.setFileAttachments(new Messaging.EmailFileAttachment[]{ attachment });
58        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ message });
59        
60        ApexPages.addMessage(new 
61            ApexPages.Message(ApexPages.Severity.INFO,
62           'Email sent with PDF attachment to ' + this.recipientEmail));
63
64        return null; // Stay on same page, even on success
65    }
66    
67    
68    /***** Form Helpers *****/
69    
70    // Ten recently-touched accounts, for the Account selection menu
71    public List<SelectOption> recentAccounts {
72        get {
73            if(null == recentAccounts){
74                recentAccounts = new List<SelectOption>();
75                for(Account acct : [SELECT Id,Name,LastModifiedDate 
76                                    FROM Account 
77                                    ORDER BY LastModifiedDate DESC 
78                                    LIMIT 10]) {
79                    recentAccounts.add(new SelectOption(acct.Id, acct.Name));
80                }
81            }
82            return recentAccounts;
83        }
84        set;
85    }
86    
87    // List of available reports, for the Summary Format selection menu
88    public List<SelectOption> reportFormats {
89        get {
90            if(null == reportFormats) {
91                reportFormats = new List<SelectOption>();
92                for(Map <String,Object> report : reports) {
93                    reportFormats.add(new SelectOption(
94                        (String)report.get('name'), (String)report.get('label')));
95                }
96            }
97            return reportFormats;
98        }
99        set;
100    }
101
102    
103    /***** Private Helpers *****/
104    
105    // List of report templates to make available
106    // These are just Visualforce pages you might print to PDF
107    private Map<String,PageReference> reportPagesIndex;
108    private List<Map<String,Object>> reports {
109        get {
110            if(null == reports) {
111                reports = new List<Map<String,Object>>();
112                // Add one report to the list of reports
113                Map<String,Object> simpleReport = new Map<String,Object>();
114                simpleReport.put('name',  'simple');
115                simpleReport.put('label', 'Simple');
116                simpleReport.put('page',   Page.ReportAccountSimple);
117                reports.add(simpleReport);
118                
119                // Add your own, more complete list of PDF templates here
120
121                // Index the page names for the reports
122                this.reportPagesIndex = new Map<String,PageReference>();
123                for(Map<String,Object> report : reports) {
124                    this.reportPagesIndex.put(
125                        (String)report.get('name'), (PageReference)report.get('page'));
126                }
127            }
128            return reports;
129        }
130        set;
131    }
132}
この Apex コントローラは、概念的に次の 4 つの部分に分割できます。
  • 先頭にある 3 つの公開プロパティは、フォームの 3 つの入力要素により送信された値を取得します。
  • sendReport() アクションメソッドは、[取引先の概要を送信] ボタンをクリックしたときに起動されます。
  • 2 つの公開ヘルパープロパティは、選択リストの 2 つの入力要素に使用する値を提供します。
  • 末尾にある非公開ヘルパーは、使用可能な PDF レポート形式のリストをカプセル化します。Visualforce ページを作成してから、そのエントリをこのセクションに追加することにより、独自のレポートを追加できます。
sendReport() アクションメソッドが起動されると、コードで次の操作が行われます。
  • フォーム項目に意味のある値があることを確認するため、基本的なエラーチェックが実行されます。

    このエラーチェックは、実際のユーザを含む取引先責任者に対応する必要があるフォームには不十分です。本番コードでは、さらに包括的なフォーム検証が実行されます。

    メモ

  • 次に、選択された取引先の値を使用して、その取引先の名前が検索されます。取引先名は、メールメッセージに追加されるテキストで使用されます。また、この検索では、実際の取引先が選択されたことを確認するため、フォームの値がさらに検証されます。
  • Messaging.SingleEmailMessage クラスを使用して、メールメッセージの宛先、件名、本文の値を設定してメールメッセージが作成されます。
  • 選択されたレポート形式に対してコードで PageReference が作成され、ページ要求パラメータが設定されます。パラメータは指定された「ID」で、その値は選択された取引先の ID に設定されます。この PageReference は、指定された取引先のコンテキストでこのページにアクセスするための特定の要求を表します。getContentAsPdf() がコールされると、参照された Visualforce ページから指定の取引先にアクセスでき、その取引先の詳細を使用してページが表示されます。
  • 最後に、PDF データが添付ファイルに追加され、前に作成したメールメッセージに添付ファイルが追加されます。そして、メッセージが送信されます。

PageReference.getContentAsPdf() を使用する場合、メソッドコールの戻り値の型は「大きなバイナリオブジェクト」を表す Blob です。Apex では、Blob データ型は型指定のないバイナリデータを表します。バイナリデータが PDF ファイルになる「application/pdf」コンテンツタイプで reportPdf 変数を Messaging.EmailFileAttachment に追加する場合にのみ、このようになります。

さらに���getContentAsPdf() へのコールは try/catch ブロックにラップされます。コールに失敗すると、catch により、期待される PDF データが例外メッセージテキストの Blob バージョンで置き換えられます。

PDF データとしての Visualforce ページの表示は、さまざまな理由により、意味的には外部サービスへのコールアウトとして処理されます。その理由の 1 つとして、外部サービスが失敗するのとまったく同じように表示サービスが失敗する可能性があることが挙げられます。たとえば、使用できない外部リソースをページで参照する場合があります。別の例としては、ページに含まれるデータが多すぎたり、表示時間が制限を超えたりする場合です。これは通常、画像フォームの場合に起こります。この理由により、Visualforce ページを Apex で PDF データとして表示する場合は、getContentAsPdf() 表示コールを常に try/catch ブロックにラップしてください。

もれがないようにするため、次に Apex コードで PDF データとして表示するレポートテンプレートページを示します。
1<apex:page showHeader="false" standardStylesheets="false"
2    standardController="Account">
3    
4    <!-- 
5    This page must be called with an Account ID in the request, e.g.:
6    https://<salesforceInstance>/apex/ReportAccountSimple?id=001D000000JRBet
7    -->
8
9    <h1>Account Summary for {! Account.Name }</h1>
10    
11    <table>
12        <tr><th>Phone</th>  <td><apex:outputText value="{! Account.Phone }"/></td></tr>
13        <tr><th>Fax</th>    <td><apex:outputText value="{! Account.Fax }"/></td></tr>
14        <tr><th>Website</th><td><apex:outputText value="{! Account.Website }"/></td></tr>
15    </table>
16
17    <p><apex:outputText value="{! Account.Description }"/></p>
18        
19</apex:page>