PDF generation versus printing

For legacy reasons, I have one complex routine that prints.
And a completely different routine that generates a PDF document.
The main reason is that I could create a custom print preview for the printing.

This is bonkers, and I am considering ditching the ‘print’ option completely, if I can find a way to use the PDF output.

Xojo printing has always been …challenging… anyway, (and I’ve never understood why people expect to see a print preview before they say what shape the page should be)

If I have a PDF :

Is it possible to silently send that to a printer?
Is it possible to generate a thumbnails document from a big document, without it just being the whole document shown small?
Does replacing the printing option by a wholly PDF export actually make sense to anyone else?

You didn’t say which platform you use/need.

For Mac your question is easy to answer: do away with your separate printing routine. Everything you want to do is easily doable with the pdf functionality from the MBS plugin.

The data in my app can be saved directly to pdf. Or it can be exported to pdf. For printing I just export one pdf and show the print dialog. Since today this even works for 64bit.

Is that a print dialog from the MBS plugins?
Or something you launch as a shell?

How do you handle the PDF you generate being “A4 portrait” shape, and the customer wanting to print on Letter landscape?

Im targetting Windows and Mac

The code is really simple: see https://forum.xojo.com/42151-nsprintoperationmbs-from-pdf

I print to A4/Portrait. The Letter is a bit shorter so this just gives larger margins. It might be a good idea to add this to the to-do list. So far nobody wants to print or export mails into Landscape.

That does seem to be Mac Only unless I missed something

It’s Mac only. AFAIK you need to go the DyndPDF route if you want PDF on Windows.

But this really depends on what you want to print. For my html DynaPDF wouldn’t make sense. Have you looked at ValentinaReports?

Sorry if this may not what you want / discard this text.

For Windows XP use, I install PDFCreator (but not PDF Architect at install time).

For windows 8.1 (I forgot), for WIndows 10, it seems that a virtual printer for PDF generation exists, but I never try.


can you call generate pdf document using xojo code??

Here is our solution for x-plat pdf printing…

On Mac MBS tools are necessary in our solution. On windows you can use external pdf viewers or dynapdf.

Public Sub print(f as FolderItem, ShowDialog as Boolean=true, nArt as integer = 0)
  if f=nil or f.Exists=false then
    if ShowDialog then MsgBox "PDF not found!"
  end if
  #if TargetWindows then
    dim s as string
    dim nError as integer
    if app.lPrintWinSelf then    // App Setting
      // Print via DynaPDF

      // Print with Dialogue
      dim TempPdf as new MyDynaPDFMBS
      call TempPdf.CreateNewPDF nil
      // import PDF
      call TempPdf.SetImportFlags( Bitwiseor(pdf.kifImportAll, pdf.kifImportAsPage))
      call TempPdf.OpenImportFile(f, 0, "")
      dim copies    as integer = 1
      dim firstPage as integer = 1
      dim lastPage  as integer = 1
      dim numPages  as integer = TempPdf.GetInPageCount // pages in PDF
      if firstPage < 1 then
        firstPage = 1
      end if
      if lastPage < numPages then
        lastPage = numPages
      end if
      for c as integer = 1 to Copies
        for i as integer = firstPage to lastPage
          call TempPdf.ImportPDFPage(i)
      TempPdf.NumberOfPages = TempPdf.GetPageCount
      if TempPdf.GetPageCount = 0 then
        if ShowDialog then MsgBox "Keine Seiten in PDF-Datei gefunden! Ausdruck nicht möglich..."
      end if
      // print
      dim r as new DynaPDFRectMBS
      r.Left = app.nPrintWinLeft // Compensate margin from xojo, app settings
      r.top = app.nPrintWinTop
      r.Bottom = app.nPrintWinBottom
      r.Right = app.nPrintWinRight
      dim flags as integer = 0 //Bitwise.BitOr(pdf.kpffNoEndDoc, pdf.kpffNoStartDoc, pdf.kpffNoStartPage)
      // app settings
      if app.lPrintWinRotateAndCenter then
        flags = Bitwise.BitOr(flags, pdf.kpffAutoRotateAndCenter)
      end if
      if app.lPrintWinColor then
        flags = Bitwise.BitOr(flags, pdf.kpffColor)
        flags = Bitwise.BitOr(flags, pdf.kpff1Bit)
      end if
      if app.lPrintWinShrinkToPrintArea then
        flags = Bitwise.BitOr(flags, pdf.kpffShrinkToPrintArea)
      end if
      TempPdf.PrinterMargin = r
      TempPdf.PrinterFlags = flags
      TempPdf.printing = true
      TempPdf.PrintingDone = false
      dim e as boolean = TempPdf.PrintPDFFileWithDialog(nil, f.NameWithoutExtensionMBS, flags, r, nil, wndYourMainWindow) 
      'TempPdf.printing = False
      'TempPdf.PrintingDone = true
      TempPdf = nil
      if not e then
        msgbox "Error while printing..."
      end if
      // Print with external program via shell
      // Examples
      // c:\\programs\\...\\PDFXCview.exe /print:showui=false %1

      // params
      //  /print:showui=false %1   for PDFXCview.exe (Tracker-Software.com)
      //  -print-to-default %1       for SumatraPDF.exe (sumatrapdfreader.org)
      //  %1 = placeholder for your pdf file name, will be replaced 

      if app.cPDFAltPrg.trim <> "" then  // app settings: print with external program
        s =  """"+app.cPDFAltPrg.trim+""" "+ app.cPDFAltPara
        s = ReplaceAll(s, "%1", """" + f.NativePath + """")
        dim xsh as new shell
        xsh.Execute s
        nError = xsh.ErrorCode
        if nError <> 0 then
          if ShowDialog then MsgBox "Error while printing... # "+str(nError)
        end if
        // try to print print via foxit
        dim r as new RegistryItem("HKEY_CLASSES_ROOT\\FoxitReader.Document\\shell\\print\\command")
        s = r.DefaultValue
        if len(s)=0 then
          if ShowDialog then MsgBox "Foxit-Reader not installed...."
          s = ReplaceAll(s, "%1", f.NativePath)
          dim sh as new shell
          sh.Execute s
        end if
      end if
    end if
    Exception rae as RegistryAccessErrorException
      if ShowDialog then MsgBox "Foxit Reader not found in Windows-Registry."
  #elseif TargetMacOS
    // Print PDF on Mac
    // open PDF
    dim doc as new PDFDocumentMBS(f)
    // define some print setting via PrintInfo
    dim PrintInfo as new NSPrintInfoMBS
    // start print operation
    dim printOperation as NSPrintOperationMBS = doc.PrintOperation(printinfo)
    // set options on operation
    printOperation.showsPrintPanel = true
    printOperation.showsProgressPanel = true
    // and run it
    call printOperation.runOperation
End Sub

Take a look at gPDF


I went the opposite direction. I abstracted the print functions wherein a Page is a collection of Print Elements - string, line, rect, filledrect, picture, etc - that have X/Y/Width/Height expressed in units of 1/100 inch. At the very last minute, the Page is scaled and rendered to the output medium. It can render to the printer or the screen or to PDF. (Or to an excel document or a tab-delim file, etc.) That way I have a single print routine regardless of the ultimate output target.

PrinterSetup / Print / Select the Virtual Printer / Print to PDF (print to the Virtual Printer). Nearly the same as Print to PDF on macOS.
(from memory, symbolic description).

Ask if this is not crystal clear.

Use the Xojo examples to print. Only difference with standard printing (print to paper) is the output goes into a pdf file.

Below is the front page generated bymy application. Read comments after the image.

Unable to show the pdf contents, so download it .

The code is imprefect, but generate the PDF AND print to paper (I do not experiment that by myself, but the Caritas manager shows me the printed papers and tell me he printed it directly withing my application (he does not print from the pdf !). That is something I do not do.

After this cover page, the project print - in columns, with header and footers, and a grey background, one line, nothing the other - the contents of the database. You can read some specs from the data base. This is what I display at application run

The Caritas logo is a png (not vector), but the text is vector text (like in the screen). Standard Xojo code to print (I took the examples from the docs as a base and “simply” add what I needed).

Once more: this is not perfect.

It does not have an image that display the document contents like when you want to print documents from TextEdit).

Did I told you that it works on macOS AND Windows (XP at first, Windows 7, and I will check Windows 10 when I get time.

So the op question (Tim) goes to me too (err. in fact I am awaiting the anwer too).

BTW: I expanded that print to print in colors (use the Listbox background colors). Thanks to this forum for the help all along the writing of this color extension.

Linux: I made tests with Mint. The application works fine, but I do not take time to try the printing.

Lots of interesting ideas here… thank you all!

Its not a ‘generate PDF’ issue… I already have DynaPDF and the PDF is fine.

The ‘job’ is getting the PDF onto paper from Xojo code.
Since I have DynaPDF, it looks like thats the solution. PrintPDFFileWithDialog looks promising.
(If only it was easier to find out what the plugins do… the documentation is so obscure…)

A little left field, but does this help?

Looks like it just needs a shell Command, so may work with Xojo as well. From what I see you already have the PDF, and just need to send it silently to a printer.