dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[Salesforce]スケジュール済みApexやトリガでVisualforceをpdfファイルに変換する方法(後編)

これの続きです。

前回までは Visualforce ページの(より正確には、PageReference クラスの)getContent() で pdf を取得しようとしてましたがだめそうなので
Visualforce テンプレートを使う方法を試してみた。

TL;DR

  • メールテンプレートのうち、Visualforce テンプレートを使うと <messaging:attachment> タグで簡単に添付ファイルを定義できる
  • <messaging:attachment> タグには Visualforce コンポーネントも使える
  • → ので、pdf 化したい Visualforce ページは Visualforce コンポーネントで定義する
  • 商談 ID などをコンポーネントに渡すためにはテンプレート側で relatedToType="[SObject名]、Apex 側で setWhatId() を使う

コード

先にコードから。
Visualforce テンプレートで作ったメールの本文は適当です。

このようにすると、スケジュール済み Apex やトリガから実行しても Visualforce を pdf 添付してメールで送ることができる。

解説

  • pdf 化したい Visualforce ページは Visualforce コンポーネント(上では VfComponent.component)として定義する
  • Visualforce テンプレートは <messaging:emailTemplate> タグで始める
  • Visualforce テンプレート内で <messaging:attachment> タグで囲った部分はそのまま添付ファイルになる
  • <messaging:attachment> タグの内側には Visualforce コンポーネントが使えるので、先ほどの VfComponent
  • スケジュール実行された ScheduledApex クラスでは、 EmailTemplate クラスから Visualforce テンプレートを取得する
  • Visualforce コンポーネント側で使いたい商談 ID は setWhatId() でセットする。そうすると Visualforce テンプレートでは {!relatedTo.xxx} として参照可能なので、さらに Visualforce コンポーネントの attribute に渡す

注意点とか

  • メールテンプレートを使っていると setTargetObjectId は必須
  • デバッグログでメールの Body を見たときにはパースされてないように見えるけど気にしない
  • setWhatId メソッド のリファレンスを見ると

省略可能。targetObjectId 項目に取引先責任者を指定する場合、whatId も指定することができます。これにより、テンプレート内の差し込み項目が適切なデータを含んでいることが確実に保証されるようになります。

と書いてるんだけど、今回のように送信先がユーザでもうまくいっているように見える。

  • GUI から Visualforce テンプレートの詳細を見るとパースエラーになってるけど気にしない

f:id:dackdive:20150710011902p:plain

リファレンス