zoukankan      html  css  js  c++  java
  • Salesforce PDF打印

    一:基础设置

    Salesforce中的PDF页面本质上还是Visualforce[简称VF]页面,所以只需要给VF页面加上一个属性[renderAs="pdf"] 即可生成一个PDF页面

    1 <apex:page renderAs="pdf">
    2     this is a Visualforce page!!! 这是一个VF页面
    3 </apex:page>

    预览页面,可以看到生成了一个PDF页面,但是只显示了英文,涉及的中文字体都没有出现

     

    对于中文,在PDF中,需要设置font-family: Arial Unicode MS;才能显示中文字体。

    添加上属性

    1 body {
    2       font-family: Arial Unicode MS;
    3       font-size:14px;
    4       font-weight:200;
    5 }

    此时还需要额外设置几个属性,applyHtmlTag="false" applyBodyTag="false"  showheader="false" 

    原因是Salesforce对自己的页面做了相当程度的封装,所以在这样的全部都是自定义的情况下,设置上面的属性将VF自带的样式关闭,此时预览页面

    可以看到中文的正常显示。需要注意的,PDF页面不支持JS,不支持文字的加粗,只能通过文字的字号大小进行区分。

    我们来看一个基本的PDF页面模板

     1 <apex:page renderAs="pdf" showheader="false" standardstylesheets="false"  applyBodyTag="false" applyHtmlTag="false"  contentType="text/html; charset=UTF-8">
     2 <html>
     3     <head>
     4         <style>
     5         body {
     6             font-family: Arial Unicode MS;
     7             font-size:14px;
     8             font-weight:200;
     9         }
    10         </style>
    11     </head>
    12      this is a Visualforce page!!! 这是一个VF页面
    13      <!-- 输入你想要的页面内容 -->
    14  </html>
    15 </apex:page>

     二:页眉和页脚

    经常需要使用的PDF页面内容肯定包括页眉和页脚的显示设置,下面用一个demo进行示范

     1 @page {
     2     @top-center {
     3         content: element(header);
     4     }
     5     @bottom-left {
     6         content: element(footer);
     7     }
     8 }
     9 div.header {
    10     display: block;
    11     height: 20px;
    12     position: running(header);
    13 }
    14 div.footer {
    15     display: block;
    16     padding: 5px;
    17     position: running(footer);
    18 }
    19 .pagenumber:before {
    20     content: counter(page);
    21 }
    22 .pagecount:before {
    23     content: counter(pages);
    24 }

    页眉页脚对应的页面代码如下

     1 <!-- 设置页眉和页脚 -->
     2 <!-- 页眉 -->
     3 <div class="header" style="border-bottom: 1px solid #ccc">
     4     <div>
     5         <img src="{!$Resource.Logo}" style="display: block;height: 20px;float:left;" />
     6         <div style="float:left;">
     7             <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;https://www.cnblogs.com/</span>
     8             <span style="font-size:12px;">
     9                 <span style="color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;博客地址:</span>
    10                 https://www.cnblogs.com/luqinghua/
    11             </span>
    12         </div>
    13         <div style="clear: both;"></div>
    14     </div>
    15 </div>
    16 <!-- 页脚 -->
    17 <div class="footer">
    18     <div style="text-align: center;"> Page <span class="pagenumber"/>/<span class="pagecount"/></div>
    19     <div style="border-top: 1px solid #ccc;text-align: center;">
    20         <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;ADD:Salesforce开发整理[八]</span>
    21         <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;TEL: 152-0721-6593</span>
    22         <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;EMAIL: luqinghua621@gmail.com</span>
    23     </div>
    24 </div>

    页面预览效果

    三:中文自动换行

    在PDF上换行,如果是前端可以使用<br/> 强制换行,或者文字内使用&#10;换行,但是经常会有传递的中文参数,如果长度超出的情况下,需要自动换行的情况,此时我们可以在后台将中文字符串转换成一个字符串的集合,再在前端页面输出,此时可以看到自动换行的效果。

    后台控制器代码

     1 public with sharing class PrintPDFController {
     2     public  List<String> list_Name{get;set;} // PDF标题
     3     public PrintPDFController() {
     4         String  CompanyName = '公司名称特别长超出你需要限制的长度比如15个字公司名称特别长超出你' 
     5                     + '需要限制的长度比如15个字公司名称特别长超出你需要限制的长度比如15'
     6                     + '个字公司名称特别长超出你需要限制的长度比如15个字';
     7         list_Name = spliteStringToList(CompanyName);
     8     }
     9 
    10 
    11     public List<String> spliteStringToList(String field){
    12         List<String> StringList = new List<String>();
    13         for(integer i = 0 ; i < field.length(); i++){                       
    14             StringList.add(field.Substring(i,i+1));
    15         }
    16         return StringList;
    17     }
    18 }

    前端输出

    1 <apex:repeat value="{!list_Name}" var="name"><apex:outputText value="{!name}"/><textarea/></apex:repeat>

    可以看到前端的预览

    所有的超出页面长度显示的中文都会自动换行显示

    四:保留系统中的长文本字段样式输出

    打印系统中的长文本字段时需要保留原本的样式进行输出,譬如在业务机会上的描述里面写这样的格式信息,在后台获取并输出

    后台控制器代码

     1 public with sharing class PrintPDFController {
     2     public Integer Index{get;set;}
     3     public List<String> IndexList{get;set;}
     4     public List<List<List<String>>> ContentList{get;set;}
     5     public Map<String,List<List<String>>> ContentMap{get;set;}
     6 
     7     public PrintPDFController() {
     8         Opportunity opp = [ SELECT 
     9                                 Id,
    10                                 Description
    11                             FROM
    12                                 Opportunity
    13                             WHERE 
    14                                 Id =:'0066F00000sAyL1QAK' Limit 1];
    15         Index = 0;
    16         IndexList = new List<String>();
    17         ContentList = new List<List<List<String>>>();
    18         ContentMap = new Map<String,List<List<String>>>();
    19         spliteString(opp.Description); 
    20     }
    21     public void spliteString(String s){
    22         Index++;
    23         IndexList.add(String.valueOf(Index));
    24         List<String> str = s.split('
    ');
    25         List<String> str_temp;
    26         List<List<String>> sTable = new List<List<String>>();
    27         for(String tr:str){
    28             str_temp = new List<String>();
    29             for(Integer i=0;i<tr.length();i++){
    30                 str_temp.add(tr.subString(i,i+1));
    31             }
    32             sTable.add(str_temp);
    33         }
    34         ContentList.add(sTable);
    35         ContentMap.put(String.valueOf(Index),sTable);
    36     }
    37 }

    前端代码

     1 <div>
     2   <h3>业务机会描述</h3>
     3   <div>
     4     <table>
     5       <apex:repeat value="{!IndexList}" var="index">
     6         <tr style="border:0px">
     7           <td width="90%" style="border:0px;font-size:13px;">
     8             <apex:repeat value="{!ContentMap[index]}" var="contentList">
     9               <apex:repeat value="{!contentList}" var="con">{!con}<textarea/></apex:repeat>
    10               <br/>
    11             </apex:repeat>
    12           </td>
    13         </tr>
    14       </apex:repeat>
    15     </table>
    16   </div>
    17 </div>

    预览页面效果

    五:小技巧汇总

    最后记录几个小技巧:

    1、控制PDF某一区域作为一个整体不能被分页切割,使用 page-break-inside:avoid; ,可用于div,span,table,tr,td等一切你想要要保持在同一个页面显示的内容;

    2、与之相对的就是强制换页使用:<P style='page-break-after:always'>&nbsp;</P> ,类似WORD中的分页符,缺点是其本身也占有一行。

    3、PDF页面不支持Javascript的使用,对于某些条件限制的需求,可以使用IF作为判断,比如

    value="{!IF(ord.Deals__c=='01-标准','■','□')}"

    或者 用于style元素中控制样式的显示

    style="{!IF(pi.Company__c!="几米",'display:none;','100%;')}"

    4、VF页面时间格式化

    <apex:outputText value="{0, date, yyyy-MM-dd}">
           <apex:param value="{!con.PlanStartDate__c}" /> 
    </apex:outputText>

    如有错漏,欢迎指正,有问题可以在评论区留言,大家共同进步。

    ----------------------------------------------------- end  -----------------------------------------------

    最后贴上本文使用的demo页面源码

    后台控制器:PrintPDFController

     1 public with sharing class PrintPDFController {
     2     public  List<String> list_Name{get;set;} // PDF标题
     3 
     4     public Integer Index{get;set;}
     5     public List<String> IndexList{get;set;}
     6     public List<List<List<String>>> ContentList{get;set;}
     7     public Map<String,List<List<String>>> ContentMap{get;set;}
     8 
     9     public PrintPDFController() {
    10         String  CompanyName = '公司名称特别长超出你需要限制的长度比如15个字公司名称特别长超出你' 
    11                     + '需要限制的长度比如15个字公司名称特别长超出你需要限制的长度比如15'
    12                     + '个字公司名称特别长超出你需要限制的长度比如15个字';
    13         list_Name = spliteStringToList(CompanyName);
    14 
    15         Opportunity opp = [ SELECT 
    16                                 Id,
    17                                 Description
    18                             FROM
    19                                 Opportunity
    20                             WHERE 
    21                                 Id =:'0066F00000sAyL1QAK' Limit 1];
    22 
    23         Index = 0;
    24         IndexList = new List<String>();
    25         ContentList = new List<List<List<String>>>();
    26         ContentMap = new Map<String,List<List<String>>>();
    27 
    28         spliteString(opp.Description); 
    29     }
    30 
    31 
    32     public List<String> spliteStringToList(String field){
    33         List<String> StringList = new List<String>();
    34         for(integer i = 0 ; i < field.length(); i++){                       
    35             StringList.add(field.Substring(i,i+1));
    36         }
    37         return StringList;
    38     }
    39 
    40     public void spliteString(String s){
    41         Index++;
    42         IndexList.add(String.valueOf(Index));
    43         List<String> str = s.split('
    ');
    44         List<String> str_temp;
    45         List<List<String>> sTable = new List<List<String>>();
    46         for(String tr:str){
    47             str_temp = new List<String>();
    48             for(Integer i=0;i<tr.length();i++){
    49                 str_temp.add(tr.subString(i,i+1));
    50             }
    51             sTable.add(str_temp);
    52         }
    53         ContentList.add(sTable);
    54         ContentMap.put(String.valueOf(Index),sTable);
    55     }
    56 }

    前端VF页面

     1 <apex:page renderAs="pdf" showheader="false" standardstylesheets="false"  applyBodyTag="false" applyHtmlTag="false"  contentType="text/html; charset=UTF-8" controller="PrintPDFController">
     2 <html>
     3     <head>
     4         <style>
     5         body {
     6             font-family: Arial Unicode MS;
     7             font-size:14px;
     8             font-weight:200;
     9         }
    10         @page {
    11             @top-center {
    12                 content: element(header);
    13             }
    14             @bottom-left {
    15                 content: element(footer);
    16             }
    17         }
    18         div.header {
    19             display: block;
    20             height: 20px;
    21             position: running(header);
    22         }
    23         div.footer {
    24             display: block;
    25             padding: 5px;
    26             position: running(footer);
    27         }
    28         .pagenumber:before {
    29             content: counter(page);
    30         }
    31         .pagecount:before {
    32             content: counter(pages);
    33         }
    34         </style>
    35     </head>
    36      this is a Visualforce page!!! 这是一个VF页面
    37      <br/>
    38      <!-- 输入你想要的页面内容 -->
    39     <apex:repeat value="{!list_Name}" var="name"><apex:outputText value="{!name}"/><textarea/></apex:repeat>
    40     <br/>
    41 
    42     <div>
    43         <h3>业务机会描述</h3>
    44         <div>
    45           <table>
    46             <apex:repeat value="{!IndexList}" var="index">
    47               <tr style="border:0px">
    48                 <td width="90%" style="border:0px;font-size:13px;">
    49                   <apex:repeat value="{!ContentMap[index]}" var="contentList">
    50                     <apex:repeat value="{!contentList}" var="con">{!con}<textarea/></apex:repeat>
    51                     <br/>
    52                   </apex:repeat>
    53                 </td>
    54               </tr>
    55             </apex:repeat>
    56           </table>
    57         </div>
    58       </div>
    59 
    60      <!-- 设置页眉和页脚 -->
    61      <!-- 页眉 -->
    62     <div class="header" style="border-bottom: 1px solid #ccc">
    63         <div>
    64             <img src="{!$Resource.Logo}" style="display: block;height: 20px;float:left;" />
    65             <div style="float:left;">
    66                 <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;https://www.cnblogs.com/</span>
    67                 <span style="font-size:12px;">
    68                     <span style="color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;博客地址:</span>
    69                     https://www.cnblogs.com/luqinghua/
    70                 </span>
    71             </div>
    72             <div style="clear: both;"></div>
    73         </div>
    74     </div>
    75     <!-- 页脚 -->
    76     <div class="footer">
    77         <div style="text-align: center;"> Page <span class="pagenumber"/>/<span class="pagecount"/></div>
    78         <div style="border-top: 1px solid #ccc;text-align: center;">
    79             <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;ADD:Salesforce开发整理[八]</span>
    80             <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;TEL: 152-0721-6593</span>
    81             <span style="font-size:12px;color: #808080;">&nbsp;&nbsp;&nbsp;&nbsp;EMAIL: luqinghua621@gmail.com</span>
    82         </div>
    83     </div>
    84  </html>
    85 </apex:page>
  • 相关阅读:
    性能02篇-性能测试工具介绍
    网关协议:CGI和WSGI
    Spring Cloud与微服务构建:Spring Cloud简介
    前端基础:HTTP 状态码详解
    Spring Cloud与微服务构建:微服务简介
    Redis 基础:Redis 事件处理
    Redis 基础:Redis 数据类型
    Redis 基础:Redis 配置
    Django 2.0 学习(22):Django CSRF
    Django 2.0 学习(21):Django Session
  • 原文地址:https://www.cnblogs.com/luqinghua/p/9326665.html
Copyright © 2011-2022 走看看