Select to view content in your preferred language

ArcGIS Pro Export Layout to Desktop Button

927
5
Jump to solution
08-03-2023 11:38 AM
WilliamHart1
Emerging Contributor

Hello all - I am trying to create a plug in button in Pro that takes the current layout view and exports the layout to the desktop. When I go to press the button the code runs with no problem but I am not receiving any output. If anybody could help - I would really appreciate it. Thank you.

Code below. 

 

using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Extensions;
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ArcGIS.Desktop.Internal.Core.PortalTrafficDataService.PortalDescriptionResponse;

namespace Export_Button
{
internal class Button1 : Button
{
protected override async void OnClick()
{
LayoutProjectItem layoutItem = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault(item => item.Name.Equals("Layout"));
Layout layout = await QueuedTask.Run(() => layoutItem.GetLayout());
String filePath = "//map.pdf";

// cref: ArcGIS.Desktop.Layouts.Layout.Export
// cref: ARCGIS.DESKTOP.MAPPING.PDFFORMAT
// cref: ARCGIS.DESKTOP.MAPPING.EXPORTFORMAT
// cref: ARCGIS.DESKTOP.MAPPING.EXPORTFORMAT.VALIDATEOUTPUTFILEPATH
// cref: ArcGIS.Desktop.Mapping.PDFFormat.ImageCompression
// cref: ARCGIS.DESKTOP.MAPPING.PDFFORMAT.IMAGEQUALITY
// cref: ARCGIS.DESKTOP.MAPPING.PDFFORMAT.LAYERSANDATTRIBUTES
// cref: ARCGIS.DESKTOP.MAPPING.ImageCompression
// cref: ARCGIS.DESKTOP.MAPPING.ImageQuality
// cref: ARCGIS.DESKTOP.MAPPING.LayersAndAttributes
#region Layout_ExportPDF
//Export a layout to PDF

//Create a PDF export format
PDFFormat pdf = new PDFFormat()
{
OutputFileName = filePath,
Resolution = 300,
DoCompressVectorGraphics = true,
DoEmbedFonts = true,
HasGeoRefInfo = true,
ImageCompression = ImageCompression.Adaptive,
ImageQuality = ImageQuality.Best,
LayersAndAttributes = LayersAndAttributes.LayersAndAttributes
};

//Check to see if the path is valid and export
if (pdf.ValidateOutputFilePath())
{
layout.Export(pdf); //Export the PDF
}
#endregion Layout_ExportPDF
}
}
}

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

@GKmieliauskas  is correct, you have to call the export method from the MCT.  Your example code worked fine for after i made a few correction and added some error checking:

 

protected override async void OnClick()
{
  try
  {
    LayoutProjectItem layoutItem = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault(item => item.Name.Equals("Layout")) ?? throw new Exception("Layout not found");
    Layout layout = await QueuedTask.Run(() => layoutItem.GetLayout());
    String filePath = @"c:\temp\map.pdf";

    //Create a PDF export format
    PDFFormat pdf = new()
    {
      OutputFileName = filePath,
      Resolution = 300,
      DoCompressVectorGraphics = true,
      DoEmbedFonts = true,
      HasGeoRefInfo = true,
      ImageCompression = ImageCompression.Adaptive,
      ImageQuality = ImageQuality.Best,
      LayersAndAttributes = LayersAndAttributes.LayersAndAttributes
    };

    //Check to see if the path is valid and export
    if (!pdf.ValidateOutputFilePath())
      throw new Exception($@"Invalid path: {filePath}");
    await QueuedTask.Run(() => layout.Export(pdf)); //Export the PDF
  }
  catch (Exception ex)
  {
    MessageBox.Show("Error: " + ex.ToString());
  }
}

 

Running the sample code above results in a c:\temp\map.pdf file:

Wolf_0-1691412906493.png

I fixed the ProSnippet so that the Export method is now called from within QueuedTask.Run.  

Thanks for pointing this out.

 

 

View solution in original post

5 Replies
WilliamHart1
Emerging Contributor

Also when changing the filepath an error shows up when pressing the button that shows "ArcGIS.Core.CalledOnWrongThreadException: 'This method or property must be called on the thread this object was created on." on the layout.Export(pdf) line of code. Any help would be greatly appreciated. Thanks!

0 Kudos
GKmieliauskas
Esri Regular Contributor

Hi,

You need call layout.Export(pdf) on the MCT. It means , it must be enclosed in QueuedTask.Run.

//Check to see if the path is valid and export
if (pdf.ValidateOutputFilePath())
{
  await QueuedTask.Run(() =>
  {
    layout.Export(pdf); //Export the PDF
  });
}
0 Kudos
WilliamHart1
Emerging Contributor

Thank you for the response. With that update, there is no map export and the only thing that happens is the script shown below in the output window of Visual Studio. This solution did relieve the "CalledOnWrongThread" error.  

"The thread 0x4fe4 has exited with code 0 (0x0).
The thread 0x333c has exited with code 0 (0x0).
The thread 0x5ff8 has exited with code 0 (0x0).
The thread 0x9b8 has exited with code 0 (0x0).
The thread 0x2b10 has exited with code 0 (0x0).
The thread 0x6888 has exited with code 0 (0x0).
The thread 0x563c has exited with code 0 (0x0).
The thread 0x158c has exited with code 0 (0x0).
The thread 0x8b8c has exited with code 0 (0x0).
The thread 0x70cc has exited with code 0 (0x0).
The thread 0x8b3c has exited with code 0 (0x0).
The thread 0x4ea0 has exited with code 0 (0x0).
The thread 0x7694 has exited with code 0 (0x0).
The thread 0x87bc has exited with code 0 (0x0).
The thread 0x7ad0 has exited with code 0 (0x0).
The thread 0x6588 has exited with code 0 (0x0).
The thread 0x7280 has exited with code 0 (0x0).
The thread 0x7610 has exited with code 0 (0x0)."

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

@GKmieliauskas  is correct, you have to call the export method from the MCT.  Your example code worked fine for after i made a few correction and added some error checking:

 

protected override async void OnClick()
{
  try
  {
    LayoutProjectItem layoutItem = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault(item => item.Name.Equals("Layout")) ?? throw new Exception("Layout not found");
    Layout layout = await QueuedTask.Run(() => layoutItem.GetLayout());
    String filePath = @"c:\temp\map.pdf";

    //Create a PDF export format
    PDFFormat pdf = new()
    {
      OutputFileName = filePath,
      Resolution = 300,
      DoCompressVectorGraphics = true,
      DoEmbedFonts = true,
      HasGeoRefInfo = true,
      ImageCompression = ImageCompression.Adaptive,
      ImageQuality = ImageQuality.Best,
      LayersAndAttributes = LayersAndAttributes.LayersAndAttributes
    };

    //Check to see if the path is valid and export
    if (!pdf.ValidateOutputFilePath())
      throw new Exception($@"Invalid path: {filePath}");
    await QueuedTask.Run(() => layout.Export(pdf)); //Export the PDF
  }
  catch (Exception ex)
  {
    MessageBox.Show("Error: " + ex.ToString());
  }
}

 

Running the sample code above results in a c:\temp\map.pdf file:

Wolf_0-1691412906493.png

I fixed the ProSnippet so that the Export method is now called from within QueuedTask.Run.  

Thanks for pointing this out.

 

 

WilliamHart1
Emerging Contributor
This worked. Thank you!
0 Kudos