需求:在Visualforce内进行页面分页,并且数据量非常大,至少一个页面要显示5000件以上,甚至几十万件
大数据量的分页显示,这样的需求很常见,所以在Visualforce内进行大数据量页面分页,我们在这里简单地说明一下。
希望对大家有所帮助。
实现步骤(1):创建Apex代码
关于使用SOQL的LIMIT和OFFSET来进行分页,很简单,关键的代码就是下面这一句SOQL。
另外的下一页next,上一页previous方法无非是对OffsetSize的值进行修改,并重新查询 。
leadViewQuery = leadViewQuery + whereStr + 'LIMIT :LimitSize OFFSET :OffsetSize';
/**
* @description : 使用SOQL的LIMIT和OFFSET来进行分页
* @author : SalesforceGogogo.com
* @last modified on : 2023/08/31
* @last modified by : SalesforceGogogo.com
**/
public with sharing class GoodPaging {
// 検索結果件数
public Integer searchCount { get; set; }
public Integer viewrecCount { get; set; }
// 検索リードリスト
public List<Lead> searchLeadList { get; set; }
// 次ページ、前ページ用項目------------Start
private integer totalRecs = 0;
public integer OffsetSize = 0;
private integer LimitSize= 50;
private static final Integer PAGE_SIZE =50; // 1ページあたりの表示件数
public Integer currentPage {get; private set;} // 現在選択中のページ
public Integer totalPage {get; private set;} // ページ数
public Integer firstNum {
get{
if(currentPage != null){
return PAGE_SIZE * (currentPage - 1) + 1;
}
return 0;
}
set;
}
public GoodPaging(){
searchLead();
}
//-----------------------------------------
// 検索
//-----------------------------------------
public void searchLead(){
searchWithPagnation();
// ページの総数を計算
// レコード数 / ページサイズで計算、小数部分は切り上げ
totalPage = (Integer)Math.ceil((Decimal)searchCount / LimitSize);
//System.debug('■totalPage---------------->'+ totalPage);
currentPage = 1;
}
public void searchWithPagnation(){
this.searchCount = 0;
String leadViewQuery =
'Select ' +
' Id ' +
' ,Name ' +
' ,Phone ' +
' ,MobilePhone ' +
' ,State ' +
' ,City ' +
' ,Street ' +
' ,CreatedDate ' +
' ,FirstName ' +
' ,LastName ' +
' ,Company ' +
' ,ConvertedAccountId ' +
'From ' +
' Lead ' +
'Where ' +
' IsDeleted = false ' ;
String leadCntQuery =
'Select ' +
' Count(Id) cnt ' +
'From ' +
' Lead ' +
'Where ' +
' IsDeleted = false ' ;
// 関連データからの条件絞り込みを実行する必要がある場合は関連データから検索を行う
String whereStr = '';
leadViewQuery = leadViewQuery + whereStr + 'LIMIT :LimitSize OFFSET :OffsetSize';
System.debug('■leadViewQuery---------------->'+ leadViewQuery);
List<Lead> searchLeadListQuery = Database.query(leadViewQuery);
System.debug('■searchLeadListQuery---------------->'+ searchLeadListQuery);
this.searchLeadList = Database.query(leadViewQuery);
System.debug('■searchLeadList.Size()---------------->'+ this.searchLeadList.Size());
leadCntQuery = leadCntQuery + whereStr;
AggregateResult[] groupedResults = Database.query(leadCntQuery);
// 検索結果件数を保持
this.searchCount = Integer.valueOf(groupedResults.get(0).get('cnt'));
//System.debug('■searchCount---------------->'+ searchCount);
if(this.searchCount >= 50){
this.viewrecCount = 50;
}else{
this.viewrecCount = this.searchCount;
}
}
//Pageing対応-------------------Start
public void FirstPage()
{
OffsetSize = 0;
searchWithPagnation();
}
public void previous()
{
OffsetSize = OffsetSize - LimitSize;
searchWithPagnation();
currentPage--;
}
public void next()
{
OffsetSize = OffsetSize + LimitSize;
searchWithPagnation();
currentPage++;
}
public void LastPage()
{
OffsetSize = totalrecs - math.mod(totalRecs,LimitSize);
searchWithPagnation();
}
//前のページがあるかどうか
public boolean getenablePrev()
{
if(OffsetSize == 0 || currentPage == 1){
return false;
}else{
return true;
}
}
//次のページがあるかどうか
public boolean getenableNext()
{
if((OffsetSize + LimitSize) > totalRecs){
return false;
}else{
return true;
}
}
//Pageing対応-------------------End
}
实现步骤(2):创建Visualforce Page代码
<apex:page standardStylesheets="false" controller="GoodPaging" lightningStylesheets="false" sidebar="false" showHeader="false" docType="html-5.0" id="page">
<style>
.table .thead-dark th {
color: #000;
background-color: #e9dfe5;
border-color: #dee2e6;
}
</style>
<apex:form >
<table id="searchTable" class="table table-bordered table-striped" style="width:100%;height:1000px;table-layout: auto;">
<thead>
<tr>
<th colspan="10" style="border-bottom: solid 0.1px #e9dfe5;height:45px;" class="sorter-false filter-false" >
<div style="width:50%;float:left;">検索結果:{!searchCount}件 表示件数:{!viewrecCount}件</div>
<div style="width:50%;float:left;text-align: right;">
<!-- ページネーション -->
<apex:outputPanel layout="none" rendered="{!enablePrev}">
<apex:commandLink value="< 前" action="{!previous}" />
<apex:outputLabel value=" | " />
</apex:outputPanel>
<apex:outputLabel value="{!currentPage}/{!totalPage}" />
<apex:outputPanel layout="none" rendered="{!enableNext}">
<apex:outputLabel value=" | " />
<apex:commandLink value="次 >" action="{!next}" />
</apex:outputPanel>
</div>
</th>
</tr>
<tr class="thead-dark">
<th width="3%"><span>No.</span></th>
<th width="10%"><span>登録日</span></th>
<th width="22%"><span>住所</span></th>
<th width="15%"><span>顧客名</span></th>
<th width="10%"><span>携帯</span></th>
<th width="10%"><span>日時</span></th>
</tr>
</thead>
<apex:variable var="rowNum" value="{!firstNum}" />
<apex:repeat value="{!searchLeadList}" var="scLead" >
<tr class="dataLineNomal" style="height:45px;" id="{!scLead.Id}">
<td style="font-size:12px;">
<apex:outputText value="{!rowNum}"/>
</td>
<td style="font-size:12px;"><apex:outputField value="{!scLead.CreatedDate}"/></td>
<td style="font-size:12px;padding:10px 10px 0px 10px;">
<div><apex:outputText value="{!scLead.State}" /></div>
<div><apex:outputText value="{!scLead.City}" /></div>
<div><apex:outputText value="{!scLead.Street}" /></div>
</td>
<td style="font-size:12px;padding:10px 10px 0px 10px;">
<div><div class="mapTColumnHeader">姓</div><apex:outputLink value="/{!scLead.Id}">{!scLead.FirstName}</apex:outputLink></div>
<div><div class="mapTColumnHeader">名</div><apex:outputLink value="/{!scLead.Id}">{!scLead.LastName}</apex:outputLink></div>
</td>
<td style="font-size:12px;padding:10px 10px 0px 10px;">
<div><div class="mapTColumnHeader">携帯</div><apex:outputText value="{!scLead.MobilePhone}"/></div>
</td>
<apex:variable var="rowNum" value="{!rowNum+1}"/>
</tr>
</apex:repeat>
</table>
</apex:form>
</apex:page>
参考页面
How to do pagination on a large dataset in Apex
https://www.linkedin.com/pulse/how-do-pagination-large-dataset-apex-zlatko-petrov/
实现效果
这个截图不太好,数据量太少,最好是有至少5000件以上的数据 。
我想说的是,
这个ViewState里面的数据数量,就是一页面的内容。其余页面的内容,我们使用SOQL的LIMIT和OFFSET的特性,就可以不查询出来,不放到List里面去,不放到List里面,就不会占用ViewState的容量。