Author: Massimo Brini
How to print programmatically from my Delphi app to my PDFWriter driver, setting
the correct filename?
Answer:
Overview
Last week we have seen how to create programmatically a report with a PDF report
engine. Now let's try to use the original solution from Adobe for the same purpose
and how to leverage the existing reports without having to recode them (the main
drawback of a pdf-engine based solution).
If you want to print a report (e.g. QReport) directly to PDF without annoying "Save
as..." pop up windows, you've got to face 2 different problems.
First of all, you must set programmatically the printer inside the exe and force
the Report Engine to print directly. The difficulty and the technique depends on
the report engine you have choosen.
Then, PDFWriter wasn't designed for automation of simple tasks, for use by
developers or for unattended operations, like the ones that occur on servers and
batch processing systems, so you will have to use some workarounds.
Worst of all, although there are some techniques to print to a specific filename
with Acrobat, these techniques change from version to version of Adove Acrobat and
even depending on the Operating System you use (pls note that I haven't tested yet
the new Acrobat 5.0 version).
Solution
Let's start with the first problem. Every Report Engine has its own rules, however
I will use for my example QR, the most commonly used VCL solution.
You can set the printer with the PrinterSettings.PrinterIndex property; if set to
-1 QRprints directly tothe default printer. Pls note that you aren't forced to show
the form with QR (but, of course, you have to create it, which can be a problema in
some kind of applications who don't admit forms)
1
2 QRLabelForm.QuickRep1.PrinterSettings.PrinterIndex := -1; // use the default printer
3 QRLabelForm.QuickRep1.Print; // print
(Please note that depending on the reporting engine and the PDF Driver, a
progression windows could appear)
We have solved the first little problem, let's look for the second.
Pay attention: you must act differently whether you use WinNT/2K or Win9x.
If you have Acrobat 3.0x or + on Win9x the solution is to modify from your delphi
exe/dll the Win.ini as follows:
[Acrobat PDFWriter]
PDFFileName=C:\WINDOWS\TEMP\TMP.PDF // your favourite path...
bDocInfo=0
To print to a particular filename, you should take care to modify the win.ini file
every time, being sure that no one else is using the Printer Driver in the same
moment (should it happen, abnormal errors, wrong filnames and other problems will
surely arise). Of course, as web applications are multithreaded by nature, you must
also prepare a lock/unlock system to avoid concurrent requests in this case. (I
think that only a mad would use a printer driver in a web app, but "never say
never")
If you have Acrobat 4.0 or + and WinNT/2K things are slightly different.
Though the Adobe documentation affirms that concurrent printing is supported in
this combination od Product/OS, my tests have showed that after a 3/4 users a
multithreaded server app would crash or behave erratically; I would suggest to use
this solution on a Server, but it is almost theoretically possible.
If you your OS is WinNT/2K you have to modify registry settings instead of .ini
files.
In brief: you should look for the key "HKEY_CURRENT_USER\Software\Adobe\Acrobat
PDFWriter" and adding/modifying a key like this (second parameter is a string value
of course):
"PDFFileName", "c:\typethefilenameyoupreferhere.pdf"; pay attention, please: if you
don't use the asterisk as last character, the string could be killed in regedit!
Now add a second key pair, which will be "bDocInfo", "0" (again string value)
As I don't think you're going to modify the registry programmatically, I would
suggest to make these changes to obtain a default file destination, and after every
pdf file creation I would rename the file. (Of course, if you want to feel new
sensations and love risk, there are some VCL components which permits you to modify
the registry; just don' use this on your web server or your boss' PC!)
Recently heard of the possibility to change via ini file the dest PDFFileName in
WinNT, too. It uses the file
"c:\winnt\system32\spool\drivers\w32x86\2\__pdf.ini" and uses the same syntax used
for W9x. Haven't tried yet, but looks interesting.
Conclusions
Using the PDFWriter driver gives you the best quality available and leverages your
investiments on report engines, but remember that the solution lacks in
programmatical control and can be a risk in unattended operations and/or
multithreaded/multiuser environments.
Also, keep in mind that the cost of the driver is high; if you want to use a
printer driver based soution, yoou should consider to substitute the Adobe one with
other ones, like the shareware from Dane Prairie (only Win2K) or Zeon (also Win9x),
which are more affordable and have a similar behaviour in front of developer's
needs.
Another similar solution could be the use of Ghostscript, but remember that it
***isn't free for commercial use*** (many people infringe the licence thinking of
it as a free product).
Reference
From Adobe's KB:
http://www.adobe.com/support/techdocs/66ca.htm
http://www.adobe.com/support/techdocs/66ca.htm
From West Wind Technologies
http://www.west-wind.com/presentations/pdfwriter/pdfwriter.htmhttp://www.west-wind.c
om/presentations/pdfwriter/pdfwriter.htm
(example with FoxPro and ASP, with semaphore system to avoid concurrency problems)
|