ThinkGeo.com    |     Documentation    |     Premium Support

Printing does send job to printer when app deployed to servers?

it is working on dev machine (map sent to the default local printer as expected).

Is there any reason not working when deployed to remote servers?



Thanks,


Hi Guangming, 
  
 I remembered in our printing sample, you can choose sent print to which printer. 
  
 Could you please let me know how you implement that? 
  
 Regards, 
  
 Don

the one you referred to is prob: map.print() called from the client side in javascript. 
  
 I have to customize my map on what to print. 
  
 here is the server side MapAction: 
         [MapActionFilter] 
         public string PrintMap(Map map, GeoCollection args) 
         { 
             #region Init: parameters, no file type 
             string result = string.Empty; 
  
             string rid = args[0].ToString(); 
             bool includeLegend = Convert.ToBoolean(args[2].ToString()); 
             bool includeScaleLine = Convert.ToBoolean(args[3].ToString()); 
  
             GetUserSettings_Result repSet = mapRepository.GetUserSettings(rid); 
             string[] Locations = ((string)args[1]).Split(’,’); 
             // in lat/long degrees 
             RectangleShape currentMapExt = new RectangleShape(double.Parse(Locations[0]), 
                 double.Parse(Locations[3]), 
                 double.Parse(Locations[2]), 
                 double.Parse(Locations[1]));  
             #endregion 
  
             // holds all real map layers to print 
             LayerOverlay mapOverlay = map.CustomOverlays[0] as LayerOverlay; //CustomOverlayName 
             try 
             { 
                 //an empty PagePrinterLayer 
                 PagePrinterLayer prl = new PagePrinterLayer(PrinterPageSize.AnsiA, PrinterOrientation.Portrait); 
  
                 #region for re-projection: find main map layer 
                 MsSql2008FeatureLayer myMainMapLayer = null; 
                 foreach (Layer layer in mapOverlay.Layers) 
                 { 
                     MsSql2008FeatureLayer theLayer = (MsSql2008FeatureLayer)layer; 
  
                     // find main map Layer 
                     // if (null == theLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Where(x => x.GetType() == typeof(ClassBreakStyle)).First()) return; 
                     if (theLayer.IsVisible || theLayer.Name.Equals(repSet.MainMapLayer, StringComparison.InvariantCultureIgnoreCase)) 
                     { 
                         myMainMapLayer = theLayer; 
                         break; 
                     } 
  
                 }  
                 #endregion 
  
                 #region for Re-projection of feature layers 
                 Proj4Projection theProjection = new Proj4Projection( 
                 Proj4Projection.GetDecimalDegreesParametersString(), Proj4Projection.GetGoogleMapParametersString()); 
                 myMainMapLayer.FeatureSource.Projection = theProjection; 
                 myMainMapLayer.FeatureSource.Projection.Open(); 
                 if (!myMainMapLayer.IsOpen) myMainMapLayer.Open(); 
                 Collection<Feature> features = myMainMapLayer.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns);  
                 #endregion 
  
                 PrintDocument printDoc = new PrintDocument(); 
  
                 printDoc.DefaultPageSettings.Landscape = prl.Orientation == PrinterOrientation.Landscape; // sync orientation 
                 printDoc.DefaultPageSettings.PaperSize = new PaperSize(“AnsiA”, 850, 1100); 
  
                 PrinterGeoCanvas pgc = new PrinterGeoCanvas(); 
                 pgc.DrawingArea = new Rectangle(0, 0, Convert.ToInt32(printDoc.DefaultPageSettings.PrintableArea.Width), 
                     Convert.ToInt32(printDoc.DefaultPageSettings.PrintableArea.Height)); 
                 prl.Open(); 
                 pgc.BeginDrawing(printDoc, prl.GetBoundingBox(), GeographyUnit.Meter); 
                 prl.Close(); 
  
                 // draw each map layer throug MapPrinterLayer 
                 Collection<SimpleCandidate> labelsInAllLayers = new Collection<SimpleCandidate>(); 
                 MapPrinterLayer mpl = new MapPrinterLayer(); 
  
                 mpl.Layers.Add(prl); 
                 RectangleShape pageBoundingbox = prl.GetPosition(PrintingUnit.Inch); 
                 mpl.MapUnit = GeographyUnit.Meter; 
                 mpl.MapExtent = myMainMapLayer.FeatureSource.Projection.ConvertToExternalProjection(currentMapExt); 
                 mpl.SetPosition(8, 8, pageBoundingbox.GetCenterPoint().X,  
                     pageBoundingbox.GetCenterPoint().Y, PrintingUnit.Inch); 
  
                 foreach (Layer l in mapOverlay.Layers) 
                 { 
                     if (l.IsVisible) 
                     { 
                         MsSql2008FeatureLayer theLayer2 = (MsSql2008FeatureLayer)l; 
                         if (!theLayer2.IsOpen) theLayer2.Open(); 
  
                         theLayer2.FeatureSource.Projection = theProjection; 
                         theLayer2.FeatureSource.Projection.Open(); 
                         features = theLayer2.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns); 
  
                         if (theLayer2.IsOpen) theLayer2.Close(); 
  
                         mpl.Layers.Add(l); 
                     } 
                 } 
                 if (myMainMapLayer.IsOpen) myMainMapLayer.Close(); 
  
                 #region check if include legend on map for exporting 
                 if (includeLegend && map.AdornmentOverlay.Layers.Contains(LegendLayerName)) 
                 { 
                     mpl.Layers.Add(map.AdornmentOverlay.Layers[LegendLayerName]); 
                 } 
                 #endregion 
  
                 #region Draw all feature layers on MapPrinterLayer: draw this map PrinterLayer to GeoCanvas 
  
                 mpl.Open(); 
                 mpl.IsDrawing = true; 
                 mpl.Draw(pgc, labelsInAllLayers); 
                 mpl.IsDrawing = false; 
                 mpl.Close();  
  
                 #endregion 
  
                 #region check if include Scale Line on map for exporting 
  
                 if (includeScaleLine) 
                 { 
                     ScaleLinePrinterLayer scaleLinePrinterLayer = new ScaleLinePrinterLayer(mpl); 
  
                     scaleLinePrinterLayer.MapUnit = GeographyUnit.Meter; 
                     scaleLinePrinterLayer.SetPosition(1.25, .25, 
                         pageBoundingbox.GetCenterPoint().X - 3.25, 
                         pageBoundingbox.GetCenterPoint().Y - 4.25, PrintingUnit.Inch); 
  
                     scaleLinePrinterLayer.Open(); 
                     scaleLinePrinterLayer.IsDrawing = true; 
                     scaleLinePrinterLayer.Draw(pgc, labelsInAllLayers); 
                     scaleLinePrinterLayer.IsDrawing = false; 
                     scaleLinePrinterLayer.Close(); 
  
                 } 
                 #endregion 
  
                 // stop all drawing 
                 pgc.EndDrawing(); 
  
                 if (prl.IsOpen) prl.Close(); 
             } 
             catch (Exception ex) 
             { 
                 result = “Sorry, something is wrong: exception exporting map”; 
             } 
             finally 
             { 
                 result = “went well”; 
                 // send to printer? 
                 mapOverlay.Redraw(); 
             } 
  
             return result; 
         } 
  
 On the client side: 
  
 function callSvrPrintMap(withLegend, withScaleLine) { 
     Map1.ajaxCallAction(mapControllerName, “PrintMap”, 
    { 
        rid: GetReportId(), 
        ext: Map1.getExtent(), // put it comma seperated 4 numbers 
        //fileType: fileType, 
        isLegend: withLegend, 
        isScaleLine: withScaleLine 
        //lid: layerId,       
    }, 
    function (result) { 
        // then update options to each control? 
        var resultString = result.get_responseData(); 
        if (resultString != “”) { 
            // alert(resultString); 
        } 
    }); 
  
 };

I posted a similar question and someone from your team said not possible to have printer popup windows to select a printer. 
  
 The issue here is to print to the default printer.

Hi Guangming, 
  
 The PrintDocument use your default printer, I think modify the default printer is the best solution. 
  
 And I found some code for choose target printer, I think it’s maybe helpful: 
  
  
var printDocument = new PrintDocument();

            printDocument.PrinterSettings.PrinterName = “Microsoft XPS Document Writer”;

            printDocument.PrinterSettings.DefaultPageSettings.Margins.Left = 0;
            printDocument.PrinterSettings.DefaultPageSettings.Margins.Top = 0;
            printDocument.PrinterSettings.DefaultPageSettings.Margins.Right = 0;
            printDocument.PrinterSettings.DefaultPageSettings.Margins.Bottom = 0;

            printDocument.DefaultPageSettings.PaperSize = new PaperSize(“A4”, 595, 842);

            printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
            try
            {
                printDocument.Print();
            }
            catch (InvalidPrinterException)
            {

            }
            finally
            {
                printDocument.Dispose();
            }

 
  
 Regards, 
  
 Don

we would like to open printing window for use to select which printer to print. here you set the printer hard-coded. 
  
 also, I am wondering how the original codes work after call mapOverlay.Redraw()? how does this line of code set map to the default printer on the client side? 
  
 that works when dev mode: client and server are in the same zone. 
  
 Thanks,

Hi Guangming,



I guess here is the API we used for print, please check it at msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument(v=vs.110).aspx, where you can find the codes mentioned by Don. When we call mapOverlay.Redraw(), I guess it will create a new instead of PrintGeoCanvas, thus a new PrintDocument to draw all the layers included in the mapOverlay, then export it to the printer.



I guess I have recreated the problem you mentioned, actually it’s an issue that how to print from IIS using .NET PrintDocument. I will make this thread “In Progress”, we will do more research on it, once any progress, I will update it here. 



Thanks,

Johnny

Hi Guangming,



For printDocument, as it is actually a winform library and not fit for the web application. So we don’t recommend it and I think we will modify our existing web print sample in the future.

I think here are two options you can try and both of the options are using the client side browser printer:

1. Save the map as bit map or pdf in server side and then fill it into a new page to print it.

                   


var win = window.open();
                    // In order to avoid a compressing, we would like to select a “Landscape” layout int the printer settings. Otherwise, you need to calculate the image width and height based on the element size.
                    win.document.write(“img width=‘100%’ height=‘100%’ src=’” + canvas.toDataURL() + “’/>”);
                    win.print();
                    win.location.reload();




2. Using some third-party js library to print the html dom element. Recently, I created a print sample with a js library named “html2canvas” and print the map or even the whole page very well, I hope it will be helpful. Here is a test video screencast.com/t/GAdnEZ6n4feO

 and sample attached.



Thanks,

Troy

PrintAMapPageSample.zip (410 KB)