How to Print An Existing PDF to Paper

DynaPDFMBS class got a print function years ago.

Many years ago I did this on Windows by controlling Adobe Reader through shell commands. I don’t know if those still exist/work currently though. I’ve also used Sumatra PDF on Windows through shell commands. In both cases it was seamless, with the user never having to interact with anything other than my program.

I’ve never tried on a Mac before, but I believe you could print the PDFs directly with the lpr command through a shell.

Thank you Anthony! It appears that Sumatra is GPLv3, and my understanding is that would prohibit me from including it (er, installing it) as a part of my application (which is closed-source). I’d prefer not to have to ask the user to go and install some 3rd party app themselves (either Adobe Reader or Sumatra) if I can avoid it, but if it comes to it I will. Thanks!

Hi Christian - I see the DynaPDF.PrintPDFFileWithDialog() method, which may be all I need. If I’m not actually generating any PDF content with DynaPDF at all - merely printing - which license do I have to purchase?

Thanks!

i open pdf this way so user have a preview and can choose what he like to print.

Function MenuManual() As Boolean
  Var f As FolderItem = SpecialFolder.Resources.Child("Manual.pdf")
  
  If f.Exists Then 
    f.Open
  Else
    MessageBox DEEN("Fehler: Anleitung nicht gefunden","error: manual file not found")
  End If
  
  Return True
  
End Function

Print in DynaPDF needs the render engine, so it’s a Pro license.

Our older examples show how to use Adobe Reader to print on Windows, but that is not as possible to automate as if we print with DynaPDF directly.

Older example with Adobe Reader:
https://www.monkeybreadsoftware.net/example-dynapdf-createandprintpdf.shtml

Newer example with print via DynaPDF:
https://www.monkeybreadsoftware.net/example-dynapdf-printpdf.shtml

See print functions in DynaPDFMBS class:

method PrintGetDevMode as String
method PrintGetDevNames(byref Driver as String, byref Device as String, byref Output as String, byref DefaultFlag as Integer) as Boolean
method PrintPDFFile(TmpDir as FolderItem, DocName as string, DCHandle as integer, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil) as Boolean
method PrintPDFFile(TmpDir as FolderItem, DocName as string, PrinterName as String, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil) as Boolean
method PrintPDFFileWithDialog(TmpDir as FolderItem, DocName as string, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil, parentWindow as Window = nil) as Boolean
method PrintPDFPage(PageNum as Integer, DocName as string, DCHandle as integer, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil) as Boolean
method PrintPDFPage(PageNum as Integer, DocName as string, PrinterName as String, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil) as Boolean
method PrintPDFPageWithDialog(PageNum as Integer, DocName as string, Flags as Integer = 0, Margin as DynaPDFRectMBS = nil, PrintParams as DynaPDFPrintParamsMBS = nil, parentWindow as Window = nil) as Boolean
method PrintSetDevMode(data as MemoryBlock) as Boolean
method PrintSetDevMode(data as String) as Boolean
method PrintSetDevNames(Driver as String, Device as String, Output as String, DefaultFlag as Integer) as Boolean

I’ve been evaluating the DynaPDF solution. It seems to print with the behavior I’d like, but it is VERY slow to do so. I’m printing an 8 page PDF, and when I print it directly from another viewer (Edge web browser, for example) the print job enters the queue at around 400kb, and all the pages come out of the printer in well under 30 seconds. When I print from DynaPDF, the same document hits the print queue at between 6-8MB (depending on whether I do grayscale, color, etc) and takes about 3 minutes total to print. There is a long pause between each page at the printer… I assume it’s because the printer has to deal with a much larger amount of data for the print job.

I assume that Edge is sending raw PostScript to the printer, while DynaPDF is sending rasterized data in some form… is there any way to speed up DynaPDF printing? Is it just this slow because I’m running the demo? Should I expect actual performance once I purchase the plugin to match what I’m seeing in the demo?

DynaPDF renders a picture of the page.
You get best speed if resolution matches, so printer doesn’t need to scale. For some users limiting to 300 dpi helps. If it uses 600 or 1200 dpi, things may be much slower.
If you print with Edge, it will translate PDF drawing commands to GDI calls for Windows, so that may be faster if no gradients or similar elements are used.

on a mac I use the “lp” command line to print the pdf file directly on the printer
I did not find the right command line for windows (and did not search for…)

Hi Jean,
Would you be kind enough to share your code re the “lp” command line to print the pdf file directly on the printer?

I have found this…
http://www.it.uu.se/datordrift/maskinpark/skrivare/cups/

and will try to use your code as a guide to print on Windows.

Thanks again.
Lennox

f is a folderitem pointing to the pdf file you want to print
sh.execute "lp "+f.shellpath

On the Mac I just open the PDF in Preview and print it. Simples.

On the mac you can actually send it to the printer with the LP command and it will print
Dont even need to open it

Thank you everyone for all the suggestions. Unfortunately, just using lp on OS X does not bring up the printer dialog box, which is part of my requirement. Here is how I ultimately am doing my printing:

On Windows: Load up the .pdf into an HTMLViewer instance, then call .print() on that instance. This brings up the printer dialog with a nice little preview that lets the user select the printer they want, their paper settings, etc. HTMLViewer has to be using the WebKit renderer.

On OS X: Use PDFDocumentMBS and NSPrintOperationMBS from the MBS plugins.

2 Likes

you can make the printerdialogbox appear in xojo code, then send the correct options to the lp command (copies, orientation, etc)

1 Like

Booked marked for future use. Thanks Kimball!

What Jean-Yves was too polite to say: you are doing it backwards. :wink:

I don’t want to have to mess with collecting and then correctly setting printer options. Too many opportunities for bugs / too fragile. That’s why I’m happy to give a few bucks to @Christian_Schmitz so that his plugin can take care of all of that for me on OS X.