此表达式返回 true 或 false 值。例如,要检查您是否有权访问标准 Lead 对象, 使用以下代码:
{!$ObjectType.Lead.accessible}
对于自定义对象,代码类似:
{!$ObjectType.MyCustomObject__c.accessible}
在哪里 自定义对象的名称。
MyCustomObject__c确保页面的一部分仅在用户 有权访问对象,请使用组件上的属性。例如,要在以下情况下显示页面块 用户有权访问 Lead 对象,您将执行以下操作:
render
<apex:page standardController="Lead">
<apex:pageBlock rendered="{!$ObjectType.Lead.accessible}">
<p>This text will display if you can see the Lead object.</p>
</apex:pageBlock>
</apex:page>
如果用户无法访问对象,最好提供备用消息。为 例:
<apex:page standardController="Lead">
<apex:pageBlock rendered="{!$ObjectType.Lead.accessible}">
<p>This text will display if you can see the Lead object.</p>
</apex:pageBlock>
<apex:pageBlock rendered="{! NOT($ObjectType.Lead.accessible) }">
<p>Sorry, but you cannot see the data because you do not have access to the Lead object.</p>
</apex:pageBlock>
</apex:page>
此页面是一个简单的用户界面。当您从 Apex 生成 PDF 文件时,所有 该操作位于 Apex 代码中。在此示例中,该代码位于指定为页面的 控制器。
PdfEmailerController
public with sharing class PdfEmailerController {
// Form fields
public Id selectedAccount { get; set; } // Account selected on Visualforce page
public String selectedReport { get; set; } // Report selected
public String recipientEmail { get; set; } // Send to this email
// Action method for the [Send Account Summary] button
public PageReference sendReport() {
// NOTE: Abbreviated error checking to keep the code sample short
// You, of course, would never do this little error checking
if(String.isBlank(this.selectedAccount) || String.isBlank(this.recipientEmail)) {
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.ERROR,
'Errors on the form. Please correct and resubmit.'));
return null; // early out
}
// Get account name for email message strings
Account account = [SELECT Name
FROM Account
WHERE Id = :this.selectedAccount
LIMIT 1];
if(null == account) {
// Got a bogus ID from the form submission
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.ERROR,
'Invalid account. Please correct and resubmit.'));
return null; // early out
}
// Create email
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setToAddresses(new String[]{ this.recipientEmail });
message.setSubject('Account summary for ' + account.Name);
message.setHtmlBody('Here\'s a summary for the ' + account.Name + ' account.');
// Create PDF
PageReference reportPage =
(PageReference)this.reportPagesIndex.get(this.selectedReport);
reportPage.getParameters().put('id', this.selectedAccount);
Blob reportPdf;
try {
reportPdf = reportPage.getContentAsPDF();
}
catch (Exception e) {
reportPdf = Blob.valueOf(e.getMessage());
}
// Attach PDF to email and send
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
attachment.setContentType('application/pdf');
attachment.setFileName('AccountSummary-' + account.Name + '.pdf');
attachment.setInline(false);
attachment.setBody(reportPdf);
message.setFileAttachments(new Messaging.EmailFileAttachment[]{ attachment });
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ message });
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.INFO,
'Email sent with PDF attachment to ' + this.recipientEmail));
return null; // Stay on same page, even on success
}
/***** Form Helpers *****/
// Ten recently-touched accounts, for the Account selection menu
public List<SelectOption> recentAccounts {
get {
if(null == recentAccounts){
recentAccounts = new List<SelectOption>();
for(Account acct : [SELECT Id,Name,LastModifiedDate
FROM Account
ORDER BY LastModifiedDate DESC
LIMIT 10]) {
recentAccounts.add(new SelectOption(acct.Id, acct.Name));
}
}
return recentAccounts;
}
set;
}
// List of available reports, for the Summary Format selection menu
public List<SelectOption> reportFormats {
get {
if(null == reportFormats) {
reportFormats = new List<SelectOption>();
for(Map <String,Object> report : reports) {
reportFormats.add(new SelectOption(
(String)report.get('name'), (String)report.get('label')));
}
}
return reportFormats;
}
set;
}
/***** Private Helpers *****/
// List of report templates to make available
// These are just Visualforce pages you might print to PDF
private Map<String,PageReference> reportPagesIndex;
private List<Map<String,Object>> reports {
get {
if(null == reports) {
reports = new List<Map<String,Object>>();
// Add one report to the list of reports
Map<String,Object> simpleReport = new Map<String,Object>();
simpleReport.put('name', 'simple');
simpleReport.put('label', 'Simple');
simpleReport.put('page', Page.ReportAccountSimple);
reports.add(simpleReport);
// Add your own, more complete list of PDF templates here
// Index the page names for the reports
this.reportPagesIndex = new Map<String,PageReference>();
for(Map<String,Object> report : reports) {
this.reportPagesIndex.put(
(String)report.get('name'), (PageReference)report.get('page'));
}
}
return reports;
}
set;
}
}
这个 Apex 控制器在概念上可以分为四个部分。
开头的三个公共属性捕获 表单上的三个输入元素。
操作方法触发 单击“发送帐户摘要”按钮时。sendReport()
两个公共帮助程序属性提供要在两个选择列表中使用的值 input 元素。
末尾的私人帮助程序封装了可能的 PDF 报告列表 格式。您可以通过创建 Visualforce 页面来添加自己的报告,然后 在本节中为其添加一个条目。
使用 时, 方法调用的返回类型为 ,其中 代表“二进制大对象”。在 Apex 中,数据类型表示非类型化二进制数据。只有当变量被添加到内容类型为 “application/pdf”,表示二进制数据成为 PDF 文件。PageReference.getContentAsPdf()BlobBlobreportPdfMessaging.EmailFileAttachment
此外,对 的调用是 包裹在块中。如果调用失败, 将希望的 PDF 数据替换为异常消息的版本 发短信。getContentAsPdf()try/catchcatchBlob
将 Visualforce 页面呈现为 PDF 数据在语义上被视为对各种外部服务的标注 原因。原因之一是渲染服务可能以与 外部服务可能会失败。例如,该页面引用了以下外部资源: 不可用。另一个例子是,当页面包含太多数据时,通常在 图像的形式 – 或渲染时间超过限制。因此,在将 Visualforce 页面渲染为 PDF 数据时,请始终将渲染调用包装在一个块中 顶点。getContentAsPdf()try/catch为了完整起见,下面是报告模板页面,该页面由 顶点 法典。
<apex:page showHeader="false" standardStylesheets="false"
standardController="Account">
<!--
This page must be called with an Account ID in the request, e.g.:
https://<salesforceInstance>/apex/ReportAccountSimple?id=001D000000JRBet
-->
<h1>Account Summary for {! Account.Name }</h1>
<table>
<tr><th>Phone</th> <td><apex:outputText value="{! Account.Phone }"/></td></tr>
<tr><th>Fax</th> <td><apex:outputText value="{! Account.Fax }"/></td></tr>
<tr><th>Website</th><td><apex:outputText value="{! Account.Website }"/></td></tr>
</table>
<p><apex:outputText value="{! Account.Description }"/></p>
</apex:page>
使用 Visualforce PDF 渲染时可用的字体
Visualforce PDF 渲染 支持一组有限的字体。要确保 PDF 输出按预期呈现,请使用 支持的字体名称。对于每种字体,列出的第一个名称是 推荐。
当页面呈现为 PDF 文件时,不支持 Web 字体。你可以使用 Visualforce 页面中的 Web 字体(当它们正常呈现时)。
测试字体呈现
您可以使用以下页面使用 Visualforce PDF 渲染测试字体渲染 发动机。
<apex:page showHeader="false" standardStylesheets="false"
controller="SaveToPDF" renderAs="{! renderAs }">
<apex:form rendered="{! renderAs != 'PDF' }" style="text-align: right; margin: 10px;">
<div><apex:commandLink action="{! print }" value="Save to PDF"/></div>
<hr/>
</apex:form>
<h1>PDF Fonts Test Page</h1>
<p>This text, which has no styles applied, is styled in the default font for the
Visualforce PDF rendering engine.</p>
<p>The fonts available when rendering a page as a PDF are as follows. The first
listed <code>font-family</code> value for each typeface is the recommended choice.</p>
<table border="1" cellpadding="6">
<tr><th>Font Name</th><th>Style <code>font-family</code> Value to Use (Synonyms)</th></tr>
<tr><td><span style="font-family: Arial Unicode MS; font-size: 14pt; ">Arial
Unicode MS</span></td><td><ul>
<li><span style="font-family: Arial Unicode MS; font-size: 14pt;">Arial Unicode MS</span></li>
</ul></td></tr>
<tr><td><span style="font-family: Helvetica; font-size: 14pt;">Helvetica</span></td>
<td><ul>
<li><span style="font-family: sans-serif; font-size: 14pt;">sans-serif</span></li>
<li><span style="font-family: SansSerif; font-size: 14pt;">SansSerif</span></li>
<li><span style="font-family: Dialog; font-size: 14pt;">Dialog</span></li>
</ul></td></tr>
<tr><td><span style="font-family: Times; font-size: 14pt;">Times</span></td><td><ul>
<li><span style="font-family: serif; font-size: 14pt;">serif</span></li>
<li><span style="font-family: Times; font-size: 14pt;">Times</span></li>
</ul></td></tr>
<tr><td><span style="font-family: Courier; font-size: 14pt;">Courier</span></td>
<td><ul>
<li><span style="font-family: monospace; font-size: 14pt;">monospace</span></li>
<li><span style="font-family: Courier; font-size: 14pt;">Courier</span></li>
<li><span style="font-family: Monospaced; font-size: 14pt;">Monospaced</span></li>
<li><span style="font-family: DialogInput; font-size: 14pt;">DialogInput</span></li>
</ul></td></tr>
</table>
<p><strong>Notes:</strong>
<ul>
<li>These rules apply to server-side PDF rendering. You might see different results
when viewing this page in a web browser.</li>
<li>Text styled with any value besides those listed above receives the default font
style, Times. This means that, ironically, while Helvetica's synonyms render as
Helvetica, using "Helvetica" for the font-family style renders as Times.
We recommend using "sans-serif".</li>
<li>Arial Unicode MS is the only multibyte font available, providing support for the
extended character sets of languages that don't use the Latin character set.</li>
</ul>
</p>
</apex:page>
上一页使用以下控制器,该控制器提供了一个简单的“保存到 PDF” 功能。
public with sharing class SaveToPDF {
// Determines whether page is rendered as a PDF or just displayed as HTML
public String renderAs { get; set; }
// Action method to "print" to PDF
public PageReference print() {
renderAs = 'PDF';
return null;
}
}
呈现为 PDF 时的组件行为
了解 Visualforce 如何 组件在转换为 PDF 时的行为对于创建呈现的页面至关重要 井。Visualforce PDF 渲染服务 呈现页面显式提供的静态 HTML 和基本 CSS。通常,不要使用 具有以下特点的组件:
依靠 JavaScript 执行操作
依赖 Salesforce 风格 床单
使用样式表或图形等在页面本身或 静态资源
检查您的 Visualforce 页面 属于这些类别之一,右键单击页面上的任意位置并查看 HTML 源代码。如果 您会看到一个引用 JavaScript 的标记 (.js) 或引用 样式表 (.css),验证生成的 PDF 文件是否显示为 预期。
要在 Microsoft Excel 电子表格中显示 Visualforce 页面数据,请使用标记上的属性,并指定 的值。contentType<apex:page>application/vnd.ms-excel
例如,以下页面构建了一个简单的联系人列表。这是一个简化的 在页面中构建数据表中所示示例的版本。
<apex:page standardController="Account">
<!-- This page must be accessed with an Account Id in the URL. For example:
https://<salesforceInstance>/apex/myPage?id=001D000000JRBet -->
<apex:pageBlock title="Contacts">
<apex:pageBlockTable value="{!account.Contacts}" var="contact">
<apex:column value="{!contact.Name}"/>
<apex:column value="{!contact.MailingCity}"/>
<apex:column value="{!contact.Phone}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
<apex:page>
<apex:stylesheet value="{!$Resource.TestStyles}"/>
<apex:outputText value="Styled Text in a sample style class" styleClass="sample"/>
</apex:page>
这是用于此示例的样式表。
.sample {
font-weight: bold;
}
使用 Lightning 设计系统
使用元素 将 Lightning Design System 合并到 Visualforce 页面中,并将它们与 Lightning Experience 的样式。此组件是上传 Lightning Design System 作为静态资源,并在 Visualforce 页面中使用它。
<apex:slds>
您不必将 Lightning Design System 作为静态资源上传。那 意味着您可以保持页面的语法简单,并保持在 250 MB 的静态资源之下 限制。要在 Visualforce 页面中使用 Lightning Design System 样式表,请在页面标记中的任意位置添加。<apex:slds />要在 Visualforce 页面中使用 Lightning Design System 样式表,请执行以下操作:
在页面中的任意位置添加 标记。<apex:slds />
将 or 属性设置为 。<apex:page>applyBodyTagapplyHtmlTagfalse
将类包含在任何 SLDS 样式上,或者 asset 父元素。slds-scope
警告
不要在元素中包装任何 Visualforce 标签。slds-scope
<apex:page standardController="Account" applyBodyTag="false">
<apex:slds />
<!-- any Visualforce component should be outside SLDS scoping element -->
<apex:outputField value="{!Account.OwnerId}" />
<div class="slds-scope">
<!-- SLDS markup here -->
</div>
</apex:page>
通常,闪电设计系统已经确定了范围。但是,如果将 or 设置为 false,则必须包含作用域类 slds-scope。在作用域类中,标记可以引用 Lightning Design System 样式和资源。applyBodyTagapplyHtmlTag
<apex:page showHeader="false">
<apex:stylesheet value="{!$Resource.customCSS}" />
<h1>Testing Custom Stylesheets</h1>
<p>This text could go on forever...<br/><br/>
But it won't!</p>
<apex:outputLink value="https://salesforce.com" styleClass="newLink">
Click here to switch to www.salesforce.com
</apex:outputLink>
</apex:page>
<apex:page>
<style type="text/css">
.asideText { font-style: italic; }
</style>
<apex:outputText style="font-weight: bold;"
value="This text is styled directly."/>
<apex:outputText styleClass="asideText"
value="This text is styled via a stylesheet class."/>
</apex:page>
若要使用 DOM ID 应用样式,请使用样式定义的 CSS 属性选择器。 请参阅定义组件的 DOM ID 的样式。如果您打算在样式表中使用图像,请使用 CSS 文件压缩图像,然后 将文件作为单个静态资源上传。例如,假设您的 CSS 文件有一个 像 以后。
body { background-image: url("images/dots.gif") }
合 整个目录和父 CSS 文件复制到单个 zip 文件中。在此示例中,zip 文件资源名称为 myStyles。
如果要应用样式,请使用样式定义的 CSS 属性选择器 属性选择器依赖于属性的定义,而不是 HTML 标记,以应用 CSS 样式。您可以在任何 Visualforce 组件上设置该值以设置其 DOM ID。但是,在呈现的 HTML 中是 通常以父母的 组件,作为 Visualforce 自动 ID 生成过程的一部分。例如,以下代码的实际 HTML 为:
ididididj_id0:myId
<apex:page>
<apex:outputText id="myId" value="This is less fancy."/>
</apex:page>
你 CSS 应该通过使用属性来考虑这一点 选择器:
<apex:page>
<style type="text/css">
[id*=myId] { font-weight: bold; }
</style>
<apex:outputText id="myId" value="This is way fancy !"/>
</apex:page>
这 选择器匹配 ID 中任何位置包含“myId”的任何 DOM ID,因此您在 Visualforce 组件上设置的 如果您打算将其用于样式目的,则在页面上是唯一的。
<apex:page showHeader="true" tabstyle="Case">
<apex:pageMessage severity="error" rendered="{!$User.UITheme = 'Theme3' &&
$User.UIThemeDisplayed != 'Theme3'}">
We've noticed that the new look and feel is enabled for your organization.
However, you can't take advantage of its brilliance. Please check with
your administrator for possible reasons for this impediment.
</apex:pageMessage>
<apex:ListViews type="Case" rendered="{!$User.UITheme = 'Theme3' &&
$User.UIThemeDisplayed = 'Theme3'}"/>
</apex:page>
function isLightningDesktop() {
return UITheme.getUITheme === "Theme4d";
}
HTML 注释和 IE 条件注释
Visualforce 删除了大多数 HTML 和 在呈现之前从页面进行 XML 注释,而不处理其内容。互联网 但是,资源管理器条件注释不会被删除,允许你包括 特定于 IE 的资源和元标记。
Visualforce 不会评估标准 HTML 注释 () 中包含的任何内容,无论注释是单行还是 多行。对于非 Internet Explorer 注释,Visualforce 编译器将 带有星号的 HTML 注释的内容。此替换使 HTML 注释 不适合在较旧的浏览器中注释掉 JavaScript 代码。<!– –>
Internet Explorer 条件注释最多 通常用于解决浏览器兼容性问题,通常使用旧版本的 即。尽管条件注释在页面上的任何地方都有效,但它们是 经常放置在页面的标签内, 它们可用于包含特定于版本的样式表或 JavaScript 兼容性“填充码”。<head>要在页面的标签中放置条件注释, 禁用标准 Salesforce header、sidebar 和 stylesheet,并添加您自己的 和 tags:
<apex:page>
<!-- Begin Default Content REMOVE THIS -->
<h1>Congratulations</h1>
This is your new Apex Page: HelloWorld
<!-- End Default Content REMOVE THIS -->
</apex:page>
此默认标记包含任何页面唯一必需的标记 — 标记 开始和结束任何页面标记。嵌入在开始和结束标记中的是纯文本, 其中一些使用标准 HTML 标记 .<apex:page><apex:page><h1>
只要保留所需的标签,就可以添加尽可能多的纯文本或有效标签 HTML 添加到此页面。例如,在输入以下内容后 代码,然后在页面编辑器中单击“保存”, 页面以粗体显示文本“Hello World!”:<apex:page>
<apex:page>
<b>Hello World!</b>
</apex:page>
提示
注意警告 – 如果您使用 HTML 保存页面,则 Visualforce 编辑器会显示警告 不要为每个打开的标签都包含匹配的结束标签。虽然 页面保存时,此格式错误的 HTML 可能会导致渲染出现问题 页。
<apex:page standardController="Account">
<apex:pageBlock title="Hello {!$User.FirstName}!">
You are viewing the {!account.name} account.
</apex:pageBlock>
</apex:page>
<apex:page standardController="Account">
<apex:pageBlock title="Hello {!$User.FirstName}!">
You are viewing the {!account.name} account.
</apex:pageBlock>
<apex:detail/>
</apex:page>
单击页面左下角的“页面编辑器”链接。这将显示 新页面的代码,应如下所示 这:<apex:page> <!-- Begin Default Content REMOVE THIS --> <h1>Congratulations</h1> This is your new Page: tabbedAccount <!-- End Default Content REMOVE THIS --> </apex:page>
请注意,“帐户”页面中没有数据。您需要指定 ID URL 中的特定帐户,就像您在前面的页面中所做的那样,例如 https:// MyDomainName.my.salesforce.com/apex/tabbedAccount?id=001D000000IRt53。 添加帐户 ID 后,您的页面应显示如下:
例如,假设您要添加有关 “帐户”页面的特定联系人。指定客户记录 ID 按默认查询字符串 参数,联系人记录 ID 由查询字符串指定 参数命名:idcid
<apex:page standardController="Account">
<apex:pageBlock title="Hello {!$User.FirstName}!">
You are displaying values from the {!account.name} account and a separate contact
that is specified by a query string parameter.
</apex:pageBlock>
<apex:pageBlock title="Contacts">
<apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" border="1">
<apex:column>
<apex:facet name="header">Name</apex:facet>
{!contact.Name}
</apex:column>
<apex:column>
<apex:facet name="header">Phone</apex:facet>
{!contact.Phone}
</apex:column>
</apex:dataTable>
</apex:pageBlock>
<apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" title="false"/>
</apex:page>
要使此示例正确呈现,您必须将 Visualforce 页面与 URL 中的有效客户和联系人 ID 相关联。例如 if 是帐户 ID 和 联系人 ID,则生成的 URL 应为:
在开始开发 Lightning Web 组件时,请确定何时重用 Visualforce 页面 以及何时将其重建为 Lightning Web 组件。考虑 在需要时进行重建:
更具吸引力和响应性的用户体验。
支持最新的 Web 内容可访问性指南 (WCAG)。
一种易于针对多种设备外形规格进行优化的体验。
提高应用性能。
Lightning Web 组件
Lightning Web 组件是使用 HTML 和现代 JavaScript 构建的自定义 HTML 元素。他们 使用核心 Web 组件标准,仅提供在浏览器中良好运行所需的内容 由 Salesforce 提供支持。因为它们是建立在浏览器中本地运行的代码之上的,所以 Lightning Web 组件是轻量级的,并提供卓越的性能。
Visualforce 标准组件和基本 Lightning Web 组件端
使用此表可查找特定 Lightning Web 组件的等效基本 Lightning Web 组件 标准 Visualforce 组件。
Visualforce 页面取代了 S 控件。尚未这样做的组织 以前使用的 S 控件无法创建它们。现有的 s 控制是 不受影响,仍可编辑。Visualforce 页面被认为是下一代 s-controls 和 应尽可能使用代替 S 控制,以提高性能和 编写它们的难易程度。下表概述了 Visualforce 页面和 S 控件。
public class findSmithAccounts {
private final List<Account> accounts;
public findSmithAccounts() {
accounts = [select Name from Account where Name LIKE ‘Smith_%’];
}
public List<Account> getSmithAccounts() {
return accounts;
}
}
<messaging:emailTemplate subject=”Embedding Apex Code” recipientType=”Contact”
relatedToType=”Opportunity”>
<messaging:htmlEmailBody>
<p>As you requested, here’s a list of all our Smith accounts:</p>
<c:smithAccounts/>
<p>Hope this helps with the {!relatedToType}.</p>
</messaging:htmlEmailBody>
</messaging:emailTemplate>
<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>