Skip to content

ProSnippets Reports

UmaHarano edited this page Nov 12, 2025 · 1 revision
Language:              C#  
Subject:               Reports  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          Esri, http://www.esri.com  
Date:                  11/7/2025  
ArcGIS Pro:            3.6  
Visual Studio:         2022  

Report Project Items

Gets all the reports in the current project

var reportsInProject = Project.Current.GetItems<ReportProjectItem>();
  foreach (var reportItem in reportsInProject)
  {
    //Do Something with the report
  }

Get a specific report

ReportProjectItem reportProjItem = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(item => item.Name.Equals("Report Name"));
  //Note: Needs QueuedTask to run
  Report reportInProject = reportProjItem?.GetReport();

Open a Report project item in a new view

//Open a report project item in a new view.
  //A report project item may exist but it may not be open in a view. 

  //Reference a report project item by name
  ReportProjectItem reportPrjItem = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(item => item.Name.Equals("MyReport"));

  //Get the report associated with the report project item
  //Note: Needs QueuedTask to run
  Report reportToOpen = reportPrjItem.GetReport();

  //Create the new pane
  IReportPane iNewReportPane = await ProApp.Panes.CreateReportPaneAsync(reportToOpen); //GUI thread

Activate an already open report view

//Note: Needs QueuedTask to run
  Report reportToActivate = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault().GetReport();
  var reportPane = FrameworkApplication.Panes.FindReportPanes(report).Last();
  if (reportPane == null)
    return;
  //Activate the pane
  (reportPane as ArcGIS.Desktop.Framework.Contracts.Pane).Activate();
  //Get the "ReportView" associated with the Report Pane.
  ReportView reportViewFromPane = reportPane.ReportView;

Reference the active report view

//Confirm if the current, active view is a report view.  If it is, do something.
ReportView activeReportView = ReportView.Active;
if (activeReportView != null)
{
  // do something
}

Refresh the report view

if (reportView == null)
    return;
  reportView.Refresh();

Zoom to whole page

//Note: Needs QueuedTask to run
  reportView.ZoomToWholePage();

Zoom to specific location on Report view

//Note: On the QueuedTask
  var detailsSection = report.Elements.OfType<ReportSection>().FirstOrDefault().Elements.OfType<ReportDetails>().FirstOrDefault();
  var bounds = detailsSection.GetBounds();
  ReportView.Active.ZoomTo(bounds);

Zoom to page width

//Process on worker thread
  reportView.ZoomToPageWidth();

Create Report

Create report

//Note: Call within QueuedTask.Run()
  //The fields in the datasource used for the report
  //This uses a US Cities dataset
  var listFields = new List<CIMReportField> {
          //Grouping should be the first field
          new CIMReportField{Name = "STATE_NAME", FieldOrder = 0, Group = true, SortInfo = FieldSortInfo.Desc}, //Group cities using STATES
          new CIMReportField{Name = "CITY_NAME", FieldOrder = 1},
          new CIMReportField{Name = "POP1990", FieldOrder = 2, },
      };
  //Definition query to use for the data source
  var defQuery = "STATE_NAME LIKE 'C%'";
  //Define the Datasource
  var reportDataSource = new ReportDataSource(featureLayer, defQuery, listFields);
  //The CIMPage defintion - page size, units, etc
  var cimReportPage = new CIMPage
  {
    Height = 11,
    StretchElements = false,
    Width = 6.5,
    ShowRulers = true,
    ShowGuides = true,
    Margin = new CIMMargin { Bottom = 1, Left = 1, Right = 1, Top = 1 },
    Units = LinearUnit.Inches
  };

  //Report template
  var reportTemplates = await ReportTemplateManager.GetTemplatesAsync();
  var reportTemplate = reportTemplates.Where(r => r.Name == "Attribute List with Grouping").First();

  //Report Styling
  var reportStyles = await ReportStylingManager.GetStylingsAsync();
  var reportStyle = reportStyles.Where(s => s == "Cool Tones").First();

  //Field Statistics
  var fieldStatisticsList = new List<ReportFieldStatistic> {
          new ReportFieldStatistic{ Field = "POP1990", Statistic = FieldStatisticsFlag.Sum}
          //Note: NoStatistics option for FieldStatisticsFlag is not supported.
      };
  var newReport = ReportFactory.Instance.CreateReport("USAReport", reportDataSource, cimReportPage, fieldStatisticsList, reportTemplate, reportStyle);

Create a report from a custom report template

//Note: Run within QueuedTask.Run()
  // get the first map in the project
  MapProjectItem item = Project.Current.GetItems<MapProjectItem>().FirstOrDefault(n => n.Name == "Cities");
  if (item == null)
    return;

  Map map = item.GetMap();
  if (map == null)
    return;

  Layer cityLayer = map.FindLayers("U.S. Cities")[0];
  if (cityLayer == null)
    return;

  // load template information
  var templatePath = System.IO.Path.Combine($@"{Project.Current.HomeFolderPath}\TemplateSimpleReportWithTokens.rptt");
  ReportCustomTemplateDefinition templateDef = ReportTemplateManager.GetCustomTemplateDefinition(templatePath);
  if (templateDef == null || templateDef.ReportTemplateDataSourceItems?.Count() < 1)
    return;

  // get template info of first data source (parent) and set its data source
  ReportCustomTemplateDataSourceInfo parentDataSourceInfo = templateDef.ReportTemplateDataSourceItems.ElementAt(0);

  parentDataSourceInfo.SetReportDataSource(cityLayer);

  TemplateTokenFieldInfoValues templateTokenFieldInfoValues = parentDataSourceInfo.TokenInfoValues;

  parentDataSourceInfo.DefinitionQuery = "STATE_NAME = 'Massachusetts'";
  templateTokenFieldInfoValues["[text-field-value-0]"] = "CITY_NAME";
  templateTokenFieldInfoValues["[text-field-name-0]"] = "City";
  templateTokenFieldInfoValues["[numeric-field-value-0]"] = "POP1990";
  templateTokenFieldInfoValues["[numeric-field-name-0]"] = "Population";

  if (templateDef.CanCreateReport())
  {
    // create the report
    report = ReportFactory.Instance.CreateReport("RelateSiblingsFromCode", templateDef);
  }
  //UI thread
  if (report != null)
  {
    //open report
    await FrameworkApplication.Panes.CreateReportPaneAsync(report);
  }

Export report to pdf

//Note: Call within QueuedTask.Run()
  //Define Export Options
  var exportOptions = new ReportExportOptions
  {
    ExportPageOption = ExportPageOptions.ExportAllPages,
    TotalPageNumberOverride = 0

  };
  //Create PDF format with appropriate settings
  string path = $@"{Project.Current.HomeFolderPath}\ReportExport.pdf";
  PDFFormat pdfFormat = new PDFFormat();
  pdfFormat.Resolution = 300;
  pdfFormat.OutputFileName = path;
  report.ExportToPDF($"{report.Name}", pdfFormat, exportOptions, true);

Import a report file

var reportFilePath = @"c:\temp\Report.rptx";
  //Note: Call within QueuedTask.Run()
  Item reportToImport = ItemFactory.Instance.Create(reportFilePath);
  Project.Current.AddItem(reportToImport as IProjectItem);

Delete a report

//Note: Call within QueuedTask.Run()
  //Reference a ReportProjectItem in a project by name
  ReportProjectItem reportItem = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(item => item.Name.Equals(reportName));
  if (reportItem != null)
    //Delete the report from the project
    Project.Current.RemoveItem(reportItem);

Modify Reports

Rename Report

//Note: Call within QueuedTask.Run()
  ReportProjectItem reportProjItem = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(item => item.Name.Equals("Report Name"));
  reportProjItem.GetReport().SetName("RenamedReport");

Modify the Report DefinitionQuery

//Note: Call within QueuedTask.Run()
  //Remove Groups
  // The fields in the datasource used for the report
  var listFields = new List<string> {
       "STATE_NAME"
      };
  report.RemoveGroups(listFields);

  //Add Group
  report.AddGroup("STATE_NAME", true, true, "");

  //Modify the Definition Query
  var defQuery = "STATE_NAME LIKE 'C%'";
  report.SetDefinitionQuery(defQuery);

Modify the report Page

//Note: Call within QueuedTask.Run()
  var cimReportPage = new CIMPage
  {
    Height = 12,
    StretchElements = false,
    Width = 6.5,
    ShowRulers = true,
    ShowGuides = true,
    Margin = new CIMMargin { Bottom = 1, Left = 1, Right = 1, Top = 1 },
    Units = LinearUnit.Inches
  };
  report.SetPage(cimReportPage);
  //Change only the report's page height
  report.SetPageHeight(12);

Add SubReport

//Note: Call within QueuedTask.Run()
  var mainReport = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(r => r.Name == "USAReports")?.GetReport();

  if (mainReport == null) return;
  //Add sub report
  var vermontReportItem = Project.Current.GetItems<ReportProjectItem>().FirstOrDefault(r => r.Name == "Vermont");
  if (vermontReportItem == null) return;
  Report vermontReport = vermontReportItem.GetReport();
  mainReport.AddSubReport(vermontReportItem, -1, true); //  If -1, the subreport is added to the end of the report.

Report Design

Get a report template

//Report Template Styles:
  //Attribute List
  //Attribute List with Grouping
  //Basic Summary
  //Basic Summary with Grouping
  //Page Per Feature
  var reportTemplates = await ReportTemplateManager.GetTemplatesAsync();
  var reportTemplate = reportTemplates.Where(r => r.Name == "Report Template Name").First();

Get a report styling

//Report Styling:
  //Black and White
  //Cool Tones
  //Warm Tones
  var reportStyles = await ReportStylingManager.GetStylingsAsync();
  var reportStyle = reportStyles.Where(s => s == "Report style name").First();

Report Elements

Get various Report sections

//Get the "ReportSection element"
  //ReportSectionElement contains the ReportHeader, ReportPageHeader, ReportDetails. ReportPageFooter, ReportFooter sections.
  var mainReportSection = report.Elements.OfType<ReportSection>().FirstOrDefault();

  //Get the ReportHeader
  var reportHeader = mainReportSection?.Elements.OfType<ReportHeader>().FirstOrDefault();

  //Get the ReportHeader
  var reportPageHeader = mainReportSection?.Elements.OfType<ReportPageHeader>().FirstOrDefault();

  //Get the "ReportDetails" within the ReportSectionElement. ReportDetails is where "fields" are.
  var reportDetailsSection = mainReportSection?.Elements.OfType<ReportDetails>().FirstOrDefault();

  //Get the ReportPageFooter
  var reportPageFooter = mainReportSection?.Elements.OfType<ReportPageFooter>().FirstOrDefault();

  //Get the ReportFooter
  var reportFooter = mainReportSection?.Elements.OfType<ReportFooter>().FirstOrDefault();

Select elements

//Get the "ReportSection element"
  //ReportSectionElement contains the ReportHeader, ReportPageHeader, ReportDetails. ReportPageFooter, ReportFooter sections.
  var mainReportSection = report.Elements.OfType<ReportSection>().FirstOrDefault();

  //ReportDetailsSection contains the "Fields"
  //Get the "ReportDetails" within the ReportSectionElement. ReportDetails is where "fields" are.
  var reportDetailsSection = mainReportSection?.Elements.OfType<ReportDetails>().FirstOrDefault();

  var elements = reportDetailsSection.Elements;
  reportDetailsSection.SelectElements(elements);

Select all elements

//Select all elements in the Report Footer.
  ReportPageFooter pageFooterSection = report.Elements.OfType<ReportSection>().FirstOrDefault().Elements.OfType<ReportPageFooter>().FirstOrDefault();
  pageFooterSection.SelectAllElements();

Get selected elements

IReadOnlyList<Element> selectedElements = report.GetSelectedElements();
  //Can also use the active ReportView
  IReadOnlyList<Element> selectedElementsFromView = ReportView.Active.GetSelectedElements();

Zoom to selected elements

//Note: Needs QueuedTask to run
  reportView.ZoomToSelectedElements();

Clear element selection

reportView.ClearElementSelection();

Find specific elements in the report based on their Name.

var reportElementsToFind = new List<string> { "ReportText1", "ReportText2" };
  var textReportElements = report.FindElements(reportElementsToFind);

Delete Elements

//Note: Needs QueuedTask to run
  var reportElementsToFind = new List<string> { "ReportText1", "ReportText2" };
  var textReportElements = report.FindElements(reportElementsToFind);
  report.DeleteElements(textReportElements);

Create a new field in the report

//This is the gap between two fields
  double fieldIncrement = 0.9388875113593206276389;
  //On the QueuedTask
  //New field to add.
  var newReportField = new CIMReportField
  {
    Name = "POP1990",
    FieldOrder = 2,
  };
  //Get the "ReportSection element"                
  var mainReportSection = report.Elements.OfType<ReportSection>().FirstOrDefault();
  if (mainReportSection == null) return;

  //Get the "ReportDetails" within the ReportSectionElement. ReportDetails is where "fields" are.
  var reportDetailsSection = mainReportSection?.Elements.OfType<ReportDetails>().FirstOrDefault();
  if (reportDetailsSection == null) return;

  //Within ReportDetails find the envelope that encloses a field.
  //We get the first CIMParagraphTextGraphic in the collection so that we can add the new field next to it.                    
  var lastFieldGraphic = reportDetailsSection.Elements.FirstOrDefault((r) =>
  {
    var gr = r as GraphicElement;
    if (gr == null) return false;
    return (gr.GetGraphic() is CIMParagraphTextGraphic ? true : false);
  });
  //Get the Envelope of the last field
  var graphicBounds = lastFieldGraphic.GetBounds();

  //Min and Max values of the envelope
  var xMinOfFieldEnvelope = graphicBounds.XMin;
  var yMinOfFieldEnvelope = graphicBounds.YMin;

  var xMaxOfFieldEnvelope = graphicBounds.XMax;
  var YMaxOfFieldEnvelope = graphicBounds.YMax;
  //create the new Envelope to be offset from the existing field

  MapPoint newMinPoint = MapPointBuilderEx.CreateMapPoint(xMinOfFieldEnvelope + fieldIncrement, yMinOfFieldEnvelope);
  MapPoint newMaxPoint = MapPointBuilderEx.CreateMapPoint(xMaxOfFieldEnvelope + fieldIncrement, YMaxOfFieldEnvelope);
  Envelope newFieldEnvelope = EnvelopeBuilderEx.CreateEnvelope(newMinPoint, newMaxPoint);

  //Create field
  GraphicElement fieldGraphic = ReportElementFactory.Instance.CreateFieldValueTextElement(reportDetailsSection, newFieldEnvelope, newReportField);

Raster and Imagery Options

Get/Set Report Options

//toggle/switch option values
  var options = ApplicationOptions.ReportOptions;

  options.PreviewAllPages = false;
  options.NumberOfPreviewPages = 25;

  options.ReportCustomTemplatePath = @"c:\temp";
Clone this wiki locally