はじめに

上図のように、お客様が新規登録した内容に応じてPDFを動的に生成し、スタッフにメール送信するという機能を実装しました。
PHPだとPDFファイルを編集できますが、Salesforceにはそのような機能がありません。
今回はSalesforceで動的にPDFを生成してメールに添付する方法を解説します。
手順
VisualforceでPDFを作成する
SalesforceでPDFを生成するには Visualforce を使います。
設定>Visualforce>新規 をクリックします。

以下のコードとその他必要な情報を入力して保存します。
<apex:page renderAs="PDF" applyhtmltag="false" showHeader="false">
<head>
<style>
body {
font-family: Arial Unicode MS;
}
</style>
</head>
<body>
テストPDF
</body>
</apex:page>
以下は必須で入力してください。
- 「renderAs="pdf"」・・・pdfとして出力
- 「applyHtmlTag="false"」・・・生成されるHTML出力に、 タグをVisualforceで自動的に追加するかどうか
- 「showHeader="false"」・・・ページにSalesforceタブのヘッダーを含めるかどうか
- 「font-family: Arial Unicode MS;」・・・日本語表示するためのフォント指定
保存したら プレビュー をクリックします。

作成したPDFを確認することができます。

プレビューを確認->Visualforceを修正...を繰り返してPDFを完成させます。
VisualforceのPDF作成ですが色々制約があり(以下参考)、デザインが複雑な場合は思った以上に大変だと思います。
- 古いCSSは使えない場合がある。(完全にデザインを再現できないケースがある。)
- 長いテキストがラップされず、枠からはみ出て見切れてしまう。
- 「renderAs="pdf"」の有無で見た目が結構変わる。(ブラウザの開発者コンソールを使って作るのが難しい)
また、PDFのテンプレートがある場合に、PDFをHTML出力してコピペするのはおすすめしません。実際にやってみましたが、期待通りの表示になりませんでした。テンプレートを見ながらゼロから地道に作成するのが良いと思います。
もし、動的に変わらない部分があるのなら、その部分だけ画像として表示させるのも一つの手段かと思います。以下のようなコードをVisualforceに追加すれば画像が表示できます。
<apex:image url="{!$Resource.静的リソースのパス}" width="100%" />
Apexコントローラーを作成して、PDFに動的に値を入れる
Visualforce に動的に値を設定するために、Apexクラスを作成します。
設定>Apexクラス>新規 をクリックします。

以下のコードとその他必要な情報を入力して保存をクリックします。
public with sharing class PDFTestCtrl {
public Blob generatePDF() {
PageReference pageRef = Page.PDFTest; // 前項で作成した Visualforce をインスタンス化する。
pageRef.getParameters().put('test', Datetime.now().format()); // Visualforce のパラメータ "test" に値を設定する。(サンプルで現在時刻を設定していますが、このような形で動的に値を設定することが可能です!)
Blob pdfBlob = pageRef.getContentAsPDF(); // Visualforce をPDFとしてBlob化する
return pdfBlob;
}
}
Apexクラスを作成したら、先ほど作成した Visualforce を少し修正します。
<apex:page renderAs="PDF" applyhtmltag="false" showHeader="false" controller="PDFTestCtrl">
<head>
<style>
body {
font-family: Arial Unicode MS;
}
</style>
</head>
<body>
テストPDF
{!$CurrentPage.parameters.test}
</body>
</apex:page>
修正点は次の二つです。
- 「controller="PDFTestCtrl"」・・・作成したApexクラスを指定します。
- 「{!$CurrentPage.parameters.test}」・・・Apexクラスで設定したパラメータの値を表示します。
メール送信する
前項で作成したApexクラスを任意の場所で実行します。
今回は開発者コンソールの匿名コンソールで実行してみます。
// PDF生成
PDFTestCtrl pdfTestCtrl = new PDFTestCtrl();
Blob pdfBlob = pdfTestCtrl.generatePDF(); // 前項で作成したApexクラスを呼び出す!!!
// メールに添付するファイルを準備
Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
efa.setFileName('pdfのファイル名.pdf');
efa.setBody(pdfBlob);
// メール送信
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new List<String>{'okada.daiki@sat.ne.jp'});
mail.setSubject('テストメールタイトル');
mail.setPlainTextBody('テストメール本文');
mail.setFileAttachments(new List<Messaging.EmailFileAttachment>{efa});
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
PDF付きのメールを送信できました!


おわりに
PHPのようなプログラミング言語だとできることが、Salesforceではできなかったり、やり方が特殊だったりします。
他にも事例があれば紹介していきたいと思います。