【Salesforce】(Tips) 外部APIで取得したPDFファイルをVisualforceで表示する

2016.12.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは植木和樹@上越妙高オフィスです。本日はVisualforceでPDFファイルを表示する方法について小ネタです。

クラスメソッドでは請求管理にSalesforceを使い、請求書の出力と郵送はMoneyforward社のMFクラウド請求書を利用しています。

お客さまから請求書の内容についてお問い合わせを受けることがたびたびあり、請求担当者や営業はMFクラウド請求書を開いて請求書を確認することになります。しかし請求書の内容を確認するためにはSalesforceを開いてサービス内容を確認する必要があり、SalesforceとMFクラウド請求書の画面を行き来することになります。

これでは少々手間なのでSalesforceからMFクラウド請求で発行された請求書PDFファイルを参照できるようにしてみました。 本日は試行錯誤の中からVisualforceでPDFファイルを表示する方法をご紹介したいと思います。

コードと解説

コードの一部を紹介します。

いろいろ調べたところ直接Visualforceの<apex:page>でPDFを表示することはできないようです。そのため<apex:iframe>タグのsrcとしてBase64エンコードしたPDFのバイナリデータを出力しています。

ポイント1:PDFファイルはiframeで表示する

data URIという方法を使ってiframeにコンテンツを埋め込むことができます。

<apex:iframe src="data:application/pdf;base64,{!content}" scrolling="off"/>

data URIについてはMozilla Developer Networkの解説が参考になりました。これをみるとIE9以降では正常に動作しない(?)かもしれません。

ポイント2:HTTPレスポンスボディをBase64エンコードする

HTTPレスポンスからBase64エンコードへの変換は地味に苦労しました。

  1. HTTPResponse#getBodyAsBlog でBLOGデータ(バイナリ)を取得する
  2. バイナリを EncodingUtil.Base64Encode でBase64エンコードする

という手順でデータ変換することができます。

APEXコードでPDFを取得してStringとして返すgetter(getContent)を用意しておき、Visualforce側で参照({!content})すればPDFを出力することができます。

ポイント3:iframeエリアをページ全体に表示する

PDFを出力するページにヘッダーエリアやサイドバーは不要なので、<apex:page>でfalseを指定して消しておきます。

次にCSSでコンテンツの高さと幅を100%指定することでウィンドウいっぱいにPDFファイルを出力することができるようになりました。

PDFを表示するリンクの用意

作成したVisualforceページをリンクやコマンドでポップアップ表示してあげればPDFファイルを表示することができます。 (openPopupはSalesforceの標準JavaScriptライブラリで読み込まれる関数です)

<apex:page>
<apex:stylesheet value="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css"/>

<apex:outputLink value="javascript:openPopup('{!URLFOR($Page.mfDisplayPDF,null,[BillingId=b.Id])}')">
<span class="fa fa-file-pdf-o"></span> PDF
</apex:outputLink>

</apex:page>

まとめ

今回はVisualforceでPDFファイルを表示する方法についてご紹介しました。

あとはMFクラウド請求書のAPIをたたいてPDFファイルを取得することができれば、Salesforceから請求書PDFが表示できそうです。 こちらについてはまた後日ブログにしたいと思います。