Maintaining a constant printout size on various deployment servers RRS feed

  • General discussion

  • Because of problems with Crystal Reports, I recently converted one of our reports to the ReportViewer control. The change was relatively quick since I had already created XSD files for the Crystal report. Once the report was complete and printing successfully (server-side) from my development server, I deployed the new version to our training server. Unfortunately, the report started printing slightly larger, enough so in fact to spill over the edges of the page. The font and all graphical elements were slightly larger. I tried it on another server and it printed slightly smaller! I think I now know why this happened: the Render call was creating an image based on the resolution of the display, which was slightly different on the three different machines. The answer was to define the bounds in which to draw the report in the DrawImage method, like so: "ev.Graphics.DrawImage(pageImage, ev.PageBounds)". It seems the DrawImage method does a good job of scaling the image. If you're interested, the complete code for server-side printing a ReportViewer report is below. [Bear in mind that this assumes you have already created some way of allowing the user to select a printer (we have a database table with a list of printers) and installed the necessary printer settings in the Default User profile.] Just call Print() to send it to the printer. No doubt this is old news to folks here, but I thought I'd share in case it helps someone.

            Private m_currentPageNumber As Integer = 1

            Private Function GetPage(ByVal pageNumber As Integer) As Byte()
                Dim warnings As Warning() = Nothing
                Dim streamids As String() = Nothing
                Dim mimeType As String = Nothing
                Dim encoding As String = Nothing
                Dim extension As String = Nothing

                Dim deviceInfoTemplate As String = "<DeviceInfo>" + _
             " <StartPage>{0}</StartPage>" + _
             " <OutputFormat>EMF</OutputFormat>" + _
                "  <PageWidth>21cm</PageWidth>" + _
                "  <PageHeight>29.7cm</PageHeight>" + _
                "  <MarginTop>1cm</MarginTop>" + _
                "  <MarginLeft>1cm</MarginLeft>" + _
                "  <MarginRight>1cm</MarginRight>" + _
                "  <MarginBottom>1cm</MarginBottom>" + _

                Dim deviceInfo As String = String.Format(deviceInfoTemplate, pageNumber)

                Return ReportViewer1.LocalReport.Render("Image", deviceInfo, mimeType, encoding, extension, streamids, warnings)
            End Function
            Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
                Dim pageImageBytes As Byte() = GetPage(m_currentPageNumber)
                Dim stream As MemoryStream = New MemoryStream(pageImageBytes)
                Dim pageImage As Metafile = New Metafile(stream)
                ev.Graphics.DrawImage(pageImage, ev.PageBounds)

                Dim temp As Byte() = GetPage(m_currentPageNumber + 1)
                If (temp.Length = 0) Then
                    ev.HasMorePages = False
                    ev.HasMorePages = True
                    m_currentPageNumber += 1
                End If
            End Sub

            Private Sub Print()
                Dim printDoc As PrintDocument = New PrintDocument()
                printDoc.PrinterSettings.PrinterName = your_printer_name
                AddHandler printDoc.PrintPage, New PrintPageEventHandler(AddressOf Me.PrintPage)
            End Sub

    Wednesday, November 7, 2007 4:20 PM