Create PDF ?

8960
76
07-20-2010 06:02 AM
CraigPerreault
New Contributor II
Does anyone have a code sample to create a PDF file using the Silverlight API?
0 Kudos
76 Replies
FengLin
New Contributor
adam,

Yes, you approach produces a high quality PDF for the map. Thanks.

Is it possible to create PDF just using current tiled layer, instead of creating a new dynamic layer from the same map service as current tiled layer?



We ended up going pretty lean on the exporter. The method we implemented is as follows

private void Map2PDF_Click(object sender, RoutedEventArgs e)
        {
            /* // Don't need the ExportPDF dialog anymore
            CMC_Viewer.Views.ExportPDF map2pdf = new CMC_Viewer.Views.ExportPDF();
            map2pdf.SetMap(this.Map);
            map2pdf.Show();
             * */

            // Display save-as dialog
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "PDF|*.pdf";
            if (!dialog.ShowDialog().Value)
            {
                return;
            }

            // Create a new dynamic layer from the same map service as current tiled layer
            ArcGISTiledMapServiceLayer tiled = this.Map.Layers[0] as ArcGISTiledMapServiceLayer;
            ArcGISDynamicMapServiceLayer dynamic = new ArcGISDynamicMapServiceLayer()
            {
                Url = tiled.Url,
                ImageFormat = ArcGISDynamicMapServiceLayer.RestImageFormat.JPG
            };


            // When the dynamic layer has initialized create the in-memory PDF document
            dynamic.Initialized += (a, b) =>
            {
                dynamic.GetUrl(this.Map.Extent,
                               (int)this.Map.ActualWidth,
                               (int)this.Map.ActualHeight,
                               delegate(string url, int width, int height, Envelope extent)
                               {
                                   // Download a new image of identical to what is currently displayed in the map
                                   WebClient webClient = new WebClient();
                                   webClient.OpenReadCompleted += (c, f) =>
                                   {
                                       // Use the dispatcher to force execution in the UI thread
                                       Dispatcher.BeginInvoke(delegate()
                                       {
                                           // Create the PDF document, set document information properties
                                           PdfDocument document = new PdfDocument();
                                           document.Info.Title = "Map";
                                           // Create a new page with the same dimensions as the browser map
                                           PdfPage page = new PdfPage(document)
                                           {
                                               Height = new XUnit(this.Map.ActualHeight, XGraphicsUnit.Presentation),
                                               Width = new XUnit(this.Map.ActualWidth, XGraphicsUnit.Presentation)
                                           };
                                           document.Pages.Add(page);

                                           // Create a graphics object for writing to the page
                                           XGraphics graphics = XGraphics.FromPdfPage(page);
                                           // Add the map image to the page
                                           XImage image = XImage.FromStream(f.Result);
                                           graphics.DrawImage(image, 0d, 0d);
                                           // Save the PDF document to the user specified filename
                                           document.Save(dialog.OpenFile());
                                           // Notify the user that we're done
                                           MessageBox.Show("Map saved to '" + dialog.SafeFileName + "'");
                                       });
                                   };
                                   webClient.OpenReadAsync(new Uri(url));
                               });
            };
            dynamic.Initialize();
        }


We found that the size of the map to be exported has to be set better than in other examples. Anyway, the code above produces a high quality map.
0 Kudos
JeffScott2
New Contributor
FYI, the PDF exporter download has included an example user control since November.  I've never seen a problem with tiled, dynamic, or graphic layers.

http://www.pierssen.com/arcgis10/silverlight.htm


Hi Mark - I was wondering if you have found a way to export the featureLayer in your great PDFExporter.cs class yet?
0 Kudos
CyndieEnfinger
New Contributor
I'm using this example to create a PDF for multiple ArcGISTiledMapServiceLayers and a GraphicsLayer:
http://www.pierssen.com/arcgis10/silverlight.htm


I'm receiving a Layer Mismatch error on the GraphicsLayer in AddBitmap(WriteableBitmap wbm)
...
        if (iCount != destPixels.Length)
        {
            MessageBox.Show("Layer mismatch encountered");
            return; // This should never happen
        }
...

There is nothing unique with the GraphicsLayer:
                <esri:GraphicsLayer ID="MyGraphicsLayer"/>

I'm not sure how to resolve this.  The destPixels.Length is > iCount.

Any help would be appreciated.
0 Kudos
PatrickBrooke
New Contributor II
This is the best way to create a pdf with a silverlight GIS web application. We have modified this sample to work in our environment with much success.

http://www.arcgis.com/home/item.html?id=8f16fdeef39c46b3952002b2d85ea5de

The maps produced, since you print to pdf from the source data, are high quality, not the 96 dpi ones you get from REST.
0 Kudos
CyndieEnfinger
New Contributor
This is the best way to create a pdf with a silverlight GIS web application. We have modified this sample to work in our environment with much success.

http://www.arcgis.com/home/item.html?id=8f16fdeef39c46b3952002b2d85ea5de

The maps produced, since you print to pdf from the source data, are high quality, not the 96 dpi ones you get from REST.


Unfortunately, the readme file doesn't give any help on how to use it in Silverlight and I'm not sure how to do that.
0 Kudos
DeminHu
New Contributor
The library seems not work for my situation:
My map including my local dynamiclly map services, bing layers, and other real time weather layers from ESRI  and NOAA. ( Cross domain )

Any suggestion will be apprecciated.
0 Kudos
JayKappy
Occasional Contributor
using PdfSharp.Pdf;

        private void PDFbutton_MouseLeftButtonUp(object sender, MouseEventArgs e)
        {
                    SaveFileDialog savePDF = new SaveFileDialog();
                    savePDF.Filter = "PDF file format|*.pdf";
                    savePDF.DefaultExt = ".pdf";
                    if (savePDF.ShowDialog() == true)
                    {
                        System.IO.Stream PDFstream = savePDF.OpenFile();
                        PDFExporter PDFNew = new PDFExporter();
                        PDFNew.SetMap(myMap);
                        PDFNew.SetOutputStream(PDFstream);
                        PDFNew.DoExport();
                    }
        }


I am trying this and getting an error on PDFExporter....sayign not defined....is there more code for this?
THanks

Anyone have a full example? There are so many different ways being discussed....like the option of not loading the entire reference....
Anyone out there that can help me....very limited knowledge here....ANYONE DOING THIS IN VB....thanks

I HAVE A SIMPLE BUTTON WITH THIS..BUT MISSING THE CLASS 'PDFExporter'....anyone have an example of that?

    
Private Sub Print_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

        Dim savePDF As New SaveFileDialog()
        savePDF.Filter = "PDF file format|*.pdf"
        savePDF.DefaultExt = ".pdf"
        If savePDF.ShowDialog() = True Then
            Dim PDFstream As System.IO.Stream = savePDF.OpenFile()
            Dim PDFNew As New PDFExporter()           
            PDFNew.SetMap(MyMap)
            PDFNew.SetOutputStream(PDFstream)
            PDFNew.DoExport()
        End If

    End Sub
0 Kudos
JayKappy
Occasional Contributor
patrickbrooke ANY help on how to integrate that into a Silverlight app that is using VB. This forum entry has confused me even more as I am seeign a few different ways to do it...I love the option to choose a map title etc...
Can you help by informing how to incorporate into silverlight?

Thanks
0 Kudos
JayKappy
Occasional Contributor
This is the best way to create a pdf with a silverlight GIS web application. We have modified this sample to work in our environment with much success.

http://www.arcgis.com/home/item.html?id=8f16fdeef39c46b3952002b2d85ea5de

The maps produced, since you print to pdf from the source data, are high quality, not the 96 dpi ones you get from REST.


Still round these parts Patrick?  Have a few questions on integrating into Silverlight....can you contact me or give soem contact info...would be greatly appeciated.
jaykappy@Yahoo.com
Thanks
0 Kudos
JonathanHouck
New Contributor III
patrickbrooke ANY help on how to integrate that into a Silverlight app that is using VB. This forum entry has confused me even more as I am seeign a few different ways to do it...I love the option to choose a map title etc... 
Can you help by informing how to incorporate into silverlight? 

Thanks


I was working with Patrick when we implemented this solution, and now that he's big timed us and moved on I'm the one doing all this in our shop.

The way we found to utilize this geoprocessing service was to create the list of parameters in our code behind and then populate them with the appropriate values. It works really good, but we haven't figured out how to format the JSON string that the "visible layers" parameter is expecting, so currently we can only control the visible layers on the template side. Our C# code to populate the parameters looks like this:

List<GPParameter> jobParameters = new List<GPParameter>();
            jobParameters.Add(new GPDouble("xMin", boundingExtent.XMin));
            jobParameters.Add(new GPDouble("yMin", boundingExtent.YMin));
            jobParameters.Add(new GPDouble("xMax", boundingExtent.XMax));
            jobParameters.Add(new GPDouble("yMax", boundingExtent.YMax));
            jobParameters.Add(new GPString("Spatial_Reference", MyMap.SpatialReference.WKID.ToString()));
            jobParameters.Add(new GPDouble("Map_Scale", Mapscale));
            jobParameters.Add(new GPString("Visiblelayers", "None"));
            jobParameters.Add(new GPString("Layout", theTemplate));
            jobParameters.Add(new GPBoolean("Include_Attributes", false));
            jobParameters.Add(new GPString("Map_Title", pdfTitle));
            jobParameters.Add(new GPString("PointGraphics", ""));            
            jobParameters.Add(new GPString("PolyGraphics", ""));


(We have a separate "if" statement in the code for LineGraphics, because one of our templates utilizes them based on a selection, but it's done the same way.)

Then we submit the job to the GP service with the following code:

Geoprocessor ExportTask = new Geoprocessor("http://......../rest/services/ExportPDF_GP/GPServer/ExportToPDF");
            ExportTask.JobCompleted += new EventHandler<JobInfoEventArgs>(ExportTask_JobCompleted);
            ExportTask.Failed += new EventHandler<TaskFailedEventArgs>(ExportTask_Failed);
            ExportTask.SubmitJobAsync(jobParameters);


The event handlers control some busy indicators and the failed throws an error message, but the completed sets the URL of the PDF that's created, which can then be accessed and opened with an on-click event.

I know there are tons of gaps in this explanation, but this tool works really great for us and we're excited about how well our users are utilizing it. If you have any questions about how we create any of the variables the parameters are using I'll be happy to answer them.
0 Kudos