You have the ability to add attachments to your Visualforce email templates. Each attachment must be encapsulated within a single <messaging:attachment> component.
Code within <messaging:attachment> can be a combination of HTML and Visualforce tags.
The previous example shows how to create a
Visualforce email template by iterating through some data and displaying it
to an email recipient. This example shows how to modify that markup
to display the data as an attachment:
<messaging:emailTemplate recipientType="Contact"
relatedToType="Account"
subject="Case report for Account: {!relatedTo.name}"
replyTo="support@acme.com">
<messaging:htmlEmailBody>
<html>
<body>
<p>Dear {!recipient.name},</p>
<p>Attached is a list of cases related to {!relatedTo.name}.</p>
<center>
<apex:outputLink value="http://www.salesforce.com">
For more detailed information login to Salesforce.com
</apex:outputLink>
</center>
</body>
</html>
</messaging:htmlEmailBody>
<messaging:attachment>
<apex:repeat var="cx" value="{!relatedTo.Cases}">
Case Number: {!cx.CaseNumber}
Origin: {!cx.Origin}
Creator Email: {!cx.Contact.email}
Case Number: {!cx.Status}
</apex:repeat>
</messaging:attachment>
</messaging:emailTemplate>
This markup renders in an email as an attached data file, without
any formatting. You can display the data in a more readable format
by using one of the following options:
Changing the Filename
The <messaging:attachment> tag has an attribute called filename that defines the name of the attached file. While it is good practice
to define an easily identifiable name, it is not required. If you
leave it undefined, Salesforce generates
a name for you.
A filename without an extension defaults to
a text file. You can render an attached file as a CSV:
<messaging:attachment filename="cases.csv">
<apex:repeat var="cx" value="{!relatedTo.Cases}">
{!cx.CaseNumber}
{!cx.Origin}
{!cx.Contact.email}
{!cx.Status}
</apex:repeat>
</messaging:attachment>
You can also render the
data as an HTML file:
<messaging:attachment filename="cases.html">
<html>
<body>
<table border="0" >
<tr>
<th>Case Number</th><th>Origin</th>
<th>Creator Email</th><th>Status</th>
</tr>
<apex:repeat var="cx" value="{!relatedTo.Cases}">
<tr>
<td><a href =
"https://na1.salesforce.com/{!cx.id}">{!cx.CaseNumber}
</a></td>
<td>{!cx.Origin}</td>
<td>{!cx.Contact.email}</td>
<td>{!cx.Status}</td>
</tr>
</apex:repeat>
</table>
</body>
</html>
</messaging:attachment>
Although you can only
define one filename for every <messaging:attachment> component, you can attach multiple files to an email.
Changing the renderAs Attribute
Similar to other
Visualforce pages, setting the
renderAs attribute to PDF on a
<messaging:attachment> component renders the attachment as a PDF. For example:
<messaging:attachment renderAs="PDF" filename="cases.pdf">
<html>
<body>
<p>You can display your {!relatedTo.name} cases as a PDF:</p>
<table border="0" >
<tr>
<th>Case Number</th><th>Origin</th>
<th>Creator Email</th><th>Status</th>
</tr>
<apex:repeat var="cx" value="{!relatedTo.Cases}">
<tr>
<td><a href =
"https://na1.salesforce.com/{!cx.id}">{!cx.CaseNumber}
</a></td>
<td>{!cx.Origin}</td>
<td>{!cx.Contact.email}</td>
<td>{!cx.Status}</td>
</tr>
</apex:repeat>
</table>
</body>
</html>
</messaging:attachment>
Limitations of the
Visualforce PDF rendering service
include the following.
- PDF is the only supported rendering service.
- The PDF rendering service renders PDF version 1.4.
- Rendering
a Visualforce page as a
PDF file is intended for pages designed and optimized for
print.
- A Visualforce page
rendered as a PDF file displays either in the browser or is downloaded,
depending on the browser’s settings. Specific behavior depends on the
browser, version, and user settings, and is outside the control of Visualforce.
- The PDF rendering service renders the markup and data on your page, but it might
not render formatting contained within the contents of rich text area fields
added to the page.
- Long lines of text that don’t have break points, such as a space or dash, can’t
be wrapped by the PDF rendering service. This most commonly happens with very
long URLs, registry entries, and so on. When these lines are wider than the
page, they increase the width of the page’s content beyond the edge of the PDF
page. This causes content to “flow” off the side of the page, cutting it
off.
- Don’t use standard components that aren’t easily formatted for print, or form
elements such as inputs or buttons, or any component that requires JavaScript to
be formatted.
- PDF rendering doesn’t support JavaScript-rendered content.
- PDF rendering isn’t supported for pages in Salesforce1.
- The font used on the page must be available on the Visualforce PDF rendering
service. Web fonts aren’t supported.
- If the PDF file fails to display all the page’s text, particularly multibyte
characters such as Japanese or accented international characters, adjust your
CSS to use a font that supports them. For
example:
<apex:page showHeader="false" applyBodyTag="false" renderAs="pdf">
<head>
<style>
body { font-family: 'Arial Unicode MS'; }
</style>
</head>
<body>
これはサンプルページです。<br/>
This is a sample page: API version 28.0
</body>
</apex:page>
“Arial
Unicode MS” is the only font supported for extended character sets that include
multibyte characters.
- If you use inline CSS styles, set the API version to 28.0 or later. Also set
<apex:page applyBodyTag="false">,
and add static, valid <head> and <body> tags to your page, as in the previous
example.
- The maximum response size when creating a PDF file must be less than 15 MB
before being rendered as a PDF file. This limit is the standard limit for
all Visualforce
requests.
- The maximum file size for a generated PDF file is 60 MB.
- The maximum total size of all images included in a generated PDF is 30 MB.
- PDF rendering doesn’t support images encoded in the data:
URI scheme format.
- The following components don’t support double-byte fonts when rendered as PDF.
- <apex:pageBlock>
- <apex:sectionHeader>
These components aren’t recommended for use in pages rendered as PDF.
- If an <apex:dataTable> or <apex:pageBlockTable> has no <apex:column> components that are
rendered, rendering the page as PDF fails. To work around this issue, set the
table component’s rendered attribute to
false if none of its child <apex:column> components are
rendered.
Adding Styles and Images
Attachments can also use stylesheets to change the way
your data is presented. Styles are associated with attachments the
same way as they are in Visualforce email templates, either as inline code, or by using a custom
component.
Attachments rendered as PDFs can reference static
resources through the $Resource global variable. This enables you to refer to an image or
stylesheet within the body of the PDF.
For example, the following
attachment includes a logo in the PDF:
<messaging:attachment renderAs="PDF" filename="cases.pdf">
<html>
<body>
<img src = "{!$Resource.logo}" />
...
</body>
</html>
</messaging:attachment>
This attachment references
a stylesheet you have saved as a static resource:
<messaging:attachment renderAs="PDF">
<html>
<link rel='stylesheet' type='text/css' href='{!$Resource.EMAILCSS}' />
<body>
...
</body>
</html>
</messaging:attachment>