Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Asynchronous Reports with the Analytics API in Apex
<apex:page controller="AsyncReportController" readOnly="true">
table.reportResults {
width: 100%;
<apex:form >
Select Report:
<apex:selectList value="{!reportId}" multiselect="false" size="1">
<apex:selectOptions value="{!availableReports}"/>
<apex:actionPoller action="{!checkForReportResults}" id="poller" reRender="reportResults" interval="5" enabled="{!reportIsRunning}" />
<apex:commandButton action="{!runReport}" reRender="poller,reportResults" value="Run Report"/>
<apex:outputPanel id="reportResults" layout="block">
<apex:outputText value="Running..." rendered="{!reportIsRunning}"/>
<apex:outputPanel rendered="{!NOT(reportIsRunning)}">
<table class="reportResults">
<apex:repeat value="{!reportResults.reportMetadata.detailColumns}" var="colName">
<th><apex:outputText value="{!reportResults.reportExtendedMetadata.detailColumnInfo[colName].label}"/></th>
<apex:repeat value="{!reportResults.factMap['T!T'].rows}" var="row">
<apex:repeat value="{!row.dataCells}" var="cell">
<td><apex:outputText value="{!cell.label}"/></td>
public with sharing class AsyncReportController {
public List<SelectOption> availableReports { get; set; }
public Id reportId { get; set; }
public Id instanceId { get; set; }
public Boolean reportIsRunning { get; set; }
private transient Reports.ReportResults reportResults;
public AsyncReportController() {
availableReports = retrieveAvailableReports();
public List<SelectOption> retrieveAvailableReports() {
List<SelectOption> reptOpts = new List<SelectOption>();
for (Report r : [
Select Id, Name
From Report
Where Format = 'Tabular'
Order By Name
]) {
reptOpts.add(new SelectOption(r.Id, r.Name));
return reptOpts;
public PageReference runReport() {
Reports.ReportInstance reportInstance = Reports.ReportManager.runAsyncReport(reportId, true);
instanceId = reportInstance.getId();
return null;
public PageReference checkForReportResults() {
Reports.ReportInstance reportInstance = Reports.ReportManager.getReportInstance(instanceId);
return null;
private void processInstance(Reports.ReportInstance reportInstance) {
reportIsRunning = reportInstance.getStatus() == 'Running' || reportInstance.getStatus() == 'New';
if (!reportIsRunning) {
reportResults = reportInstance.getReportResults();
public Reports.ReportResults getReportResults() {
return reportResults;

This comment has been minimized.

Copy link
Owner Author

@peterknolle peterknolle commented Feb 17, 2014


This comment has been minimized.

Copy link

@chandra2ravi chandra2ravi commented Jan 25, 2015

I tried this but unable to get more than 2000 records :(

Please let me know any alternatives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment