Using reports to create dynamic columns in pageBlock Table

This is 3rd series from the blogpost where i was explaining how we can show data in visualforce pages with the flexibility for the client/admin to change the fields to display on the page without changing the source code. In this example i am using Reports.

In this example, i am leveraging Salesforce's ReportManager class, which has the flexibility to run reports synchronously and async as well. I am going to use async method in this demonstration, but you can also use async methods, description here.

The source code is available at GitHub.

The code is very simple, all you need is reportId. You can hard-code in your class like i did, or you can also pass it as a parameter in the page. If you want to make it more dynamic, you can query reports from your org and show the report names as select options.




 public ID reportId {get;set;}
    public Reports.ReportResults reportResults{get;set;}
    
    public RG_getDynamicColumnsViaReports(){
        reportId='00O90000009S7X5'; //i am hard-coding the id here, but you can also pass it to parameter in page or query it
        runReport();
    }
    
    public void runReport(){
         
        reportResults = Reports.ReportManager.runReport(reportId, true);
    }

If you notice in the code above, all i am doing is running the report using ReportManager's runReport method. That is all you need. It will return the list of Reports.ReportResults class, which contains all your data.

Page:

<apex:page controller="RG_getDynamicColumnsViaReports" sidebar="false">
    <apex:includeScript value="{!URLFOR($Resource.dataTable, 'js/jquery.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.dataTable, 'js/jquery.dataTables.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.dataTable, 'css/jquery.dataTables.css')}"/>
    <apex:form >
        
        <apex:pageBlock >
           
            <table id="outtable" class="reportResults">
           <thead>
               <apex:repeat value="{!reportResults.reportMetadata.detailColumns}" var="colName">
                   <th><apex:outputText value="{!reportResults.reportExtendedMetadata.detailColumnInfo[colName].label}"/></th>
               </apex:repeat>
           </thead>

           <tbody>
               <apex:repeat value="{!reportResults.factMap['T!T'].rows}" var="row">
                   <tr>
                       <apex:repeat value="{!row.dataCells}" var="cell">
                           <td><apex:outputText value="{!cell.label}"/></td>
                       </apex:repeat>
                   </tr>
               </apex:repeat>
           </tbody>
         </table>
        </apex:pageBlock>
    </apex:form>
<script>
    //to make the table UI look nice, i am using datatables.js
    j$ = jQuery.noConflict();
            j$(document).ready( function () {
                var outTable = j$('[id$="outtable"]').DataTable({
                    
                });
            });
</script>
</apex:page>


I have used 2 repeats here in the page. One for iterating in the reportExtendedMetadata to get header labels and 2nd for getting row data, which is being stored in factMap class of exportResults. 

Here is the output:


No comments:

Post a Comment