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
You can’t perform that action at this time.