In an answer to this question...
Printing page x of y in .Net
The accepted answer included this statement...
You don't have to print it twice, you just have to simulate printing the first time.
So, how can you pass through the document one time first without any output going to the printer or screen?
You will need to create a printer device context and render your pages using that device context as a reference DC while keeping track of the number of pages you have rendered. This will have to be done outside the scope of the .NET Printing infrastructure.
Here's a shot at step 1, assumes you're working in winforms...
Private Function GetHighResolutionGraphics() As Graphics
Try
Dim HighestResolution As Printing.PrinterResolution = Nothing
Dim HighestResolutionPrinter As String = ""
Dim XResolution As Integer = Integer.MinValue
Using dlg As New PrintDialog
For Each Printer As String In Printing.PrinterSettings.InstalledPrinters
dlg.PrinterSettings.PrinterName = Printer
For Each Resolution As Printing.PrinterResolution In dlg.PrinterSettings.PrinterResolutions
Using gr As Graphics = dlg.PrinterSettings.CreateMeasurementGraphics()
If gr.DpiX > XResolution Then
HighestResolution = Resolution
HighestResolutionPrinter = Printer
XResolution = gr.DpiX
End If
End Using
Next
Next
dlg.PrinterSettings.PrinterName = HighestResolutionPrinter
dlg.PrinterSettings.DefaultPageSettings.PrinterResolution = HighestResolution
Return dlg.PrinterSettings.CreateMeasurementGraphics()
End Using
Catch ex As Exception
' handle or ignore .NET AccessViolation for certain network printers that are turned off, etc...
End Try
Return Me.CreateGraphics()
End Function
Step 2 is "simply" using the returned Reference Graphics Object with your already implemented PagePrint event code to render the pages to an appropriate bitmap while keeping track of the number of pages you're rendering. Don't forget to refactor your PagePrint Event to a separate routine that accepts a Graphics object so it can be used for Printing, Previewing and Page Numbering. Don't forget to dispose of the Graphics object and the Bitmap
using gfxReference as Graphics = GetHighResolutionGraphics()
using bmpPage as new Bitmap(gfxReference.DpiX * 8.5, gfxReference.DpiY * 11)
using gfxRender as Graphics = Graphics.FromImage(bmpPage)
gfxRender.Clear(Color.White)
// Existing PagePrint event logic goes here (uses gfxRender)
// Track Number of pages printed
end using
end using
end using
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With