A Tad More About PDF and Reports-as-Document-Sections

I’ve been helping folks to get PDF output for years using Ghostscript.  One of the things I like about it is that it answers the multiple sets of printing instructions in a document question very naturally; you can concatenate multiple postscript files together into one PDF document, and each “document section” obeys the rules with which you printed it, no problem.

PDFListener and PDFClass exploit this capability for VFP report forms, by supplying a collection of reports (in PDFListener’s case, inherited from FFC’s _ReportListener) to help you manage the process of running multiple reports in a sequence to postscript files, sending appropriate instructions to Ghostscript, and tidying up.

This isn’t a VFP-specific reporting scenario, of course.  In fact I’ve been answering lots of RS forum posts with advice like this recently:

You can find a demo app with code for printing reports without UI, using the ReportViewer control, on this page: http://www.gotreportviewer.com/. I expect it can be adapted to go to a ps printer driver and given target file information (or the ps driver setup can be set to go to a file target explicitly — but that doesn’t seem thread safe to me).

Then you can use standard postscript to PDF capabilites to convert the string of files you just wrote out.  I use Ghostscript to do this, you don’t need Adobe and you don’t need any UI for this step either. You can learn about Ghostscript here http://www.ghostscript.com/awki  There is a overview of command-line switches here
http://ghostscript.com/doc/8.54/Use.htm#Options — for your purposes, pay particular attention to the ability to create a commandfile listing all the
switches as well as all the files you wish to process in this run (more flexible than listing the files directly on the command line if your list may be long).  You may prefer to use the API directly (DLLs rather than command-line).  It’s quite extensive.

The process is simple, and really does work quite well.

But there’s an important difference between what VFP reports can do and what Reporting Services can do: in VFP’s case, we can’t get PDF output natively. On the other hand,  RS provides PDF as a native export format.  That means RS folks don’t have to go all the way down to the PS file level to use PDF files as document sections if they don’t want to.

While I think there is stuff in the Ghostscript API that will let you concatenate PDF files properly into a single document (stripping off the extra header information from each, or whatever it takes), I’m pleased to say that I’ve found another utility recently that does this job with no fuss at all.

Take a look at PDFTK.

PDFTK is a GPL, cross-platform toolkit for PDFs with no reliance on Acrobat.  And if you’re working with PDFs as your input files, you have no reliance on printer setups either; that part is already done by the time you “get here”.   I’ll quote from their relevant examples:

rem Merge Two or More PDFs into a New Document
pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf
rem or (Using Handles):
pdftk A=1.pdf B=2.pdf cat A B output 12.pdf
rem or (Using Wildcards):
pdftk *.pdf cat output combined.pdf


What could be easier?

What’s that you say? You don’t like the idea of shelling out to unmanaged code to perform this task?

And I thought java purists were annoying…

Retro is the new future

Quit whining, learn about true interop, and make the best tool for the job your new mantra.

Invoke PDFTK with Windows Power Shell if it makes you feel more au courant, more comme il faut, more with-it, or more… powerful.

I figure, since it’s taken Windows until now (Windows Server 2008?) to come up with something integrated into the OS that handles a pipeline like *nix always did, PowerShell is probably pretty good…

11 thoughts on “A Tad More About PDF and Reports-as-Document-Sections

  1. Good article; I am new to postscript/open source command line utilities. I have a .Net windows program and I want clients to have the ability to export multiple reports into a single pdf.
    Does Ghostscript and/or PDFTK need to be installed on each client that generate .pdf’s using either method?

    Thanks for your help.

  2. Hi Henry,

    Sorry for delay in response.

    Yes, you do need to install ghostscript or PDFTK or whatever utility on the machine that is doing the conversion. Which might be server, you can distribute this work and treat the action as a web service. In fact, I would say that a lot of the “free PDF conversion” facilities on the web (typically they offer FTP upload or something like that, but there are probably SOAP ones as well) are using GhostScript “underneath”.

    What’s more, you can install silently, so that the process is part of either your application setup or something that happens transparently on demand. The actual article (versus the blog post here), http://spacefold.com/articles/PDFPower.aspx, goes into some detail about this.

  3. Interesting article! Maybe someone can help us out??

    Currently we generate simple text file record dumps in VFP 6.0 for 50-60 jobs per day, using code to format the “record dump.txt” file, and then using the line TYPE record dump.txt TO PRINTER to “automatically” print the formatted text file on paper on our default HP printer.

    Without totally re-inventing the wheel, is is possible to keep formatting the text file record dumps the same way with this program, but set things up to:

    “automatically” generate a PDF file from the formatted text file (instead of going directly to the HP printer)

    “automatically” giving the PDF file a descriptive file name and folder location (instead of opening the text file in the VFP ditor, clicking File, Print, selecting ‘Adobe PDF’, clicking OK, typing in a file name for the PDF file, specifying a location for the file name, clicking OK again, etc.)??

    “automatically” set the default printer back to the HP printer (for paper-based output, for the other aspects of each job)

    Right now, each time we create record dumps we are manually (non VFP methods) specifying ‘Adobe PDF’ as the default printer, typing in the file names and folder locations manually, and resetting the HP printer back to the default printer.

    Thanks for any insite!!

  4. OK – Update from above issue!!

    We have figured out how to maintain the formatting code, reference ‘Adobe PDF’ as the current printer, output the formatted text file as a PDF file, and recall the HP printer as the default printer (see code below):

    {code to format the text file …}

    SET PRINTER FONT ‘Courier New’, 8

    set printer to name ‘Adobe PDF’

    TYPE ‘record dump.txt’ TO PRINTER

    set printer to name ‘\\\hp_office’

    This produced a properly formatted record dump in a PDF file format!!

    NOW – the only issue we have left that we always get a ‘Save PDF File As’ dialog box, defaulting to the ‘My Documents’ folder, with a default File Name of ‘Visual FoxPro.pdf’ each time.

    We would like to NOT see this dialog box displayed, and be able to specify the destination folder(s) and PDF file name(s) from within the program. Different jobs require different destination folders and file names.

    Any ideas??



  5. FYI – ‘Adobe PDF’ is installed under Printers and Faxes when installing Adobe Acrobat. It allows you to “print” to a PDF file.

  6. >>Any ideas??

    You should know not to ask me that ;-)…

    John, here’s an old trick that will do what you want:

    SET PRINTER TO NAME (GETPRINTER()) && I’ll pick a printer here
    CREATE CURSOR x (onefield m)
    APPEND MEMO onefield FROM (GETFILE(“txt”)) && this is your code-adjusted record dump file
    REPORT FORM printmemo TO FILE c:\temp\myfile.txt
    USE IN x

    The printmemo.frx is just a report form with *no* page header and footer and a single, stretching text control with the expression ONEFIELD that goes across the full detail band width.

    I don’t have an adobe PDF driver to try it with here, but I did just try it with a postscript printer and processing the resulting text file successfully using Ghostscript to a PDF, so clearly the FRX didn’t introduce any unwanted white space or pagination to the PS file.

    You can check this out in a couple of minutes “without totally reinventing the wheel”.

    That being said, you might find that your “simple text file record dumps” and your re-formatting of the same might be better done by simply creating a cursor and a report form to handle them, in the first place ;-).


  7. Thank you for your response. I have another question:

    If I have a simple Visual FoxPro table (I am using VFP version 6.0), and “copy to abc.xls type xls” (or type xl5) the resulting first row of the spreadsheet contains the correct field names in the appropriate columns, but they are always lower cased. Is there a way to “copy to” a spreadsheet and automatically keep those field names upper case?? If I view the FoxPro table with a text editor, those field names appear to be stored in the header area as upper case.

  8. Considering how primitive VFP export to Excel is, why not just COPY TO … TYPE CSV instead?

    Excel will “understand” a CSV file just as well it understands the Excel-native version that VFP provides. You can use a number of methods programmatically to strip off the header line (I’d probably use LLFFns) and to replace it with whatever headers you prefer.

  9. Thank you for this excellent article about PDF and reports-as-document-sections!

    I didn’t even know that it was possible to use Ghostscript to get PDF output.

    Anyways, the whole post was very helpful to me, though I’ll have to reread it a couple of times before I’m brave enough to try anything.

    Great Article!

Leave a Reply

Your email address will not be published. Required fields are marked *