SalesforceでPDFを動的に生成してメールに添付する

はじめに

上図のように、お客様が新規登録した内容に応じて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ではできなかったり、やり方が特殊だったりします。
他にも事例があれば紹介していきたいと思います。