「PDF として保存」機能の Visualforce ページへの追加
1<apex:page showHeader="false" standardStylesheets="false"
2 standardController="Account" extensions="SaveAsPdfExtension"
3 contentType="{! renderedContentType }" renderAs="{! renderingService }">
4
5 <!--
6 This page must be called with an Account ID in the URL, e.g.:
7 https://<salesforceInstance>/apex/AccountContactsPdf?id=001D000000JRBet
8 -->
9
10 <apex:form rendered="{! renderingService != 'PDF' }"
11 style="text-align: right; margin: 10px;">
12 <apex:commandLink action="{! saveToPdf }" value="Save to PDF">
13 <apex:param assignTo="{! renderedFileName }" value="Contact-List.pdf"/>
14 </apex:commandLink>
15 <hr/>
16 </apex:form>
17
18 <h1>Contacts for {! Account.Name}</h1>
19
20 <apex:dataTable value="{! Account.Contacts }" var="contact">
21 <apex:column headerValue="Name" value="{! contact.Name }"/>
22 <apex:column headerValue="Title" value="{! contact.Title }"/>
23 <apex:column headerValue="Phone" value="{! contact.Phone }"/>
24 <apex:column headerValue="Email" value="{! contact.Email }"/>
25 </apex:dataTable>
26
27 <hr/>
28 <!-- A little bit of info about the page's rendering;
29 see how it changes when saved as a PDF. -->
30 contentType: <apex:outputText value=" {! renderedContentType }"/><br/>
31 renderingService: <apex:outputText value=" {! renderingService }"/><br/>
32</apex:page>この例には、2 つの重要な要素があります。1 つ目の要素は、<apex:page> コンポーネントの renderAs および contentType 属性です。これらは式を使用して動的に設定されます。これらの式の値によって、ページの表示形式を制御します。
2 つ目の要素は <apex:form> で、ページを PDF に保存するためのユーザインターフェースを提供します。このフォームには、saveToPdf アクションメソッドをコールする <apex:commandLink> という要素があります。<apex:param> コンポーネントは、ファイル名を設定するためにコントローラコードで使用される PDF ファイルの名前を提供します。
フォームは、ページが HTML として表示される場合にのみ表示され、PDF 版では表示されません。このように表示するには、ページが PDF ファイルとして表示される場合に <apex:form> コンポーネントの rendered 属性を false に設定します。
1public class SaveAsPdfExtension {
2
3 // Required extension constructor (empty, no-op)
4 public SaveAsPDFExtension(ApexPages.StandardController controller) {}
5
6 // Determines what kind of rendering to use for the page request
7 public String renderingService { get; private set; }
8
9 // Allow the page to set the PDF file name
10 public String renderedFileName {
11 get;
12 set { renderedFileName = this.sanitizeFileName(value); }
13 }
14
15 // Rendered content MIME type, used to affect HTTP response
16 public String renderedContentType {
17 get {
18 String renderedContentType = 'text/html'; // the default
19
20 if( ! this.renderingAsHtml() ) {
21 // Provides a MIME type for a PDF document
22 renderedContentType = 'application/pdf';
23
24 // Add a file name for the PDF file
25 if( this.renderedFileName != null) {
26 // This is supposed to set the file name, but it doesn't work
27 renderedContentType += '#' + this.renderedFileName;
28
29 // This is a work-around to set the file name
30 ApexPages.currentPage().getHeaders().put(
31 'content-disposition', 'attachment; filename=' +
32 this.renderedFileName);
33 }
34 }
35
36 return renderedContentType;
37 }
38 }
39
40 // Are we rendering to HTML or PDF?
41 public Boolean renderingAsHtml() {
42 return ( (renderingService == null) ||
43 ( ! renderingService.startsWith('PDF')) );
44 }
45
46 // Action method to save (or "print") to PDF
47 public PageReference saveToPdf() {
48 renderingService = 'PDF';
49 return null;
50 }
51
52 // Private helper -- basic, conservative santization
53 private String sanitizeFileName(String unsafeName) {
54 String allowedCharacters = '0-9a-zA-Z-_.';
55 String sanitizedName =
56 unsafeName.replaceAll('[^' + allowedCharacters + ']', '');
57 // You might also want to check filename length,
58 // that the filename ends in '.pdf', etc.
59 return(sanitizedName);
60 }
61}この拡張のメイン部分はシンプルです。renderingService プロパティでページの表示形式 (HTML または PDF) を制御します。ページが読み込まれると値がデフォルトの null に設定され、saveToPdf アクションメソッドがコールされると「PDF」に変わります。<apex:page> コンポーネントの renderAs 属性は、renderingService を参照します。「PDF」以外の場合、ページは通常 HTML として表示されます。「PDF」の場合、ご推察のとおり、ページは PDF ファイルとして表示されます。
renderedContentType プロパティは、Visualforce <apex:page> コンポーネントの contentType 属性で使用される MIME タイプの値を提供します。この値を設定すると、サーバ応答に影響します。これにより、クライアントブラウザに応答の形式 (この場合は HTML または PDF) を通知する HTTP ヘッダーが追加されます。
また、renderedContentType プロパティは、ダウンロードされる PDF ファイルの名前も設定します。ファイル名は、ページの <apex:param> コンポーネントを使用して設定される renderedFileName プロパティから��得します。「#」とファイル名を contentType に追加すると、クライアントブラウザに送信されるファイル名が設定されると記載されていますが、この変換は機能しません。そのため、ファイル名を提供するヘッダーが設定されます。
ダウンロードされる PDF のファイル名を設定する必要がない場合、renderedContentType および renderedFileName プロパティは無視しても問題ありません。「PDF に保存」機能を追加するこの簡単なアプローチについては、「Visualforce PDF 表示の使用時に使用可能なフォント」を参照してください。