I recently had a FoxPro project which required generating PDF reports and sending them as email attachments. This can be tricky, because with anything done in volume, the key is to generate the PDFs without asking for filenames or confirmation. Ideally, the whole job should be done completely automatically. This is that it's a problem I solved years ago in Linux. The solution in Windows isn't dissimilar... the concepts are the same, but the execution details are different.
This is really two problems: one is to create the PDF, and the second to create and send the email. Let's solve the PDF generation first:
Step 1. Create an automated PostScript Printer
Go to Start->Settings->Printers and Faxes, and use the Add a Printer Wizard to create a dummy printer using any PostScript printer driver. I used the "HP Business Inkjet 2250" driver, which gives me nice color output. When it asks about a port, create a new one, and instead of selecting "FILE:" simply type in the fully qualified path to a temp directory and filename. For instance, I named my printer "MailPrint" and it prints to the port called "d:\temp\mailprint.ps". Also, it's very important
to turn off printer spooling for this printer! You might not be able to do this from the Wizard, so after the the Wizard is done, go to the printer's Properties dialog. On the Ports tab, uncheck "Enable Printer Spooling" and on the Advanced tab, check "Print Directly to Printer". This makes sure that control's not returned to your program until the driver's finished creating the file (we don't want to process the PostScript file until it's been created. Don't worry, this is still fast).
Step 2: Install GhostScript
If you've already got GhostScript installed (and I highly recommend it), then you can skip this. Otherwise, download AFPL Ghostscript, which you can get from here: http://www.cs.wisc.edu/~ghost/
. You don't need Ghostview unless you simply want to go 100% Open Source. FoxIt! Reader
is nicer, and I like it better than Acrobat reader. Ghostscript will be doing the actual conversion.
Step 3: Install MakePDF.exe
This is an optional step, as you can really do what you want with calls to GhostScript. However, Lexacorp's MakePDF.exe
has a couple of nice benefits. In addition to simplifying the command-line (which is what we're after), it gives you a worthwhile user interface and drag-n-drop converter.
At this point our PDF generation problem is solved. How to use it is described in Step 5. BTW, don't use MailPDF... it uses MAPI, and that sucks. I'll tell you why in a moment.
Now it's time to solve the mail delivery problem.
Step 4: Use SMTP (Not MAPI)
When first looking at this problem I thought, "Hey, I need a quick fix... I'll just use MAPI" (MAPI is Microsoft's Messaging API). I thought perhaps the MailPDF program might be the easiest way to get my PDF to the recipient. Wrong answer.
Here's what happens: MAPI uses whatever mail client you've got to do the work (in much the same way that TAPI uses the Microsoft Phone Dialer to do telephony). The problem is, although many mail clients are MAPI compliant, not all compliance is equal. For example, Lotus Notes and Outlook Express both refuse to send the messages automatically for security reasons. At least Notes will queue up multiple messages... OE just dies if they collide on sending. Sometimes the client responds... sometimes not. Sometimes your mail gets sent, but if it doesn't your calling program won't get notified. I'm not just picking on specific mail clients... unless you're sending one mail at a time and you've got a user there to push buttons, you should avoid, avoid, avoid MAPI.
Instead, use SMTP. If you're programming in Lotus Notes you can stop right here because it's built in to your NotesDocument class (nobody touches Notes for mail handling). For everything else, you've got a little work, but SMTP rocks (and if you're in a mixed environment remember that your Domino server is also an SMTP server).
The real trick is getting it done with no money out of pocket.
You can Google all day for free SMTP controls, and you'll be presented with page after page of really expensive stuff. Now how these guys equate "best free source code" with $199 price tags escapes me, but it's out there. You're pretty much on your own here as languages vary greatly, but TheFreeCountry.com
should be able to hook you up with something both good and really
free, whether it's for Delphi, Java, or C. You might also look at the resources collected on the Winsock Programmers FAQ
(scroll down to get to the Open Source stuff.
For FoxPro, if you're doing a project for money, I would recommend wwipstuff
, which is shareware, but it works well and is well worth about two hours of a programmer's time (which is what they're asking for it). If you're going for zero out-of-pocket expense, then you can take the extra time to roll your own class library around one of the free DLLs above.
In most Visual languages like FoxPro, you use this stuff by dropping the ActiveX control or visual class library on the form where you're going to use it. Then you simply set the properties of the message (the smtp server and sender and message details) and call the Send method.
Step 5: Put it all together and watch it work.
To use it you begin by simply printing to the printer named MailPrint. In most cases you can select this programmatically: in those cases where you can't you can make it your default printer. In some languages like FoxPro it's necessary to make sure that the printer environment is not
stored with the report when the report is created -- sadly, the default is wrong).
Then you shell to MakePDF.exe with the command-line parameters telling it where the PostScript file is, where you want the PDF file to go, and a couple of static switches to make sure it operates in quiet mode and deletes the PostScript file when it's done. Here are the switches I use:
makepdf postscriptfilename /V1.4 /D /X /L /Q /O pdffilename
This outputs an version 1.4 PDF file, deletes the PostScript file when done, exits the program when done, forces the PDF filename to lowercase, and operates in quiet mode (no notices).
In Notes and presumably some other languages you need to be concerned with getting the timing right since it doesn't appear to have an option to pause until the shell command is complete. I purposely suppress waiting in FoxPro to prevent the command window from popping up. The best thing I've found is to loop until the PostScript file disappears (which is why, other than neatness, you use the /D option to remove the source file. Then you're 100% assured that the job is done before you attempt to get a handle on the PDF. Just remember to code yourself a reasonable limit so you're not stuck in case makepdf crashed for some reason.
At that point you can attach your PDF to whatever and mail it. In Notes it's a no-brainer, it's all done in LotusScript or Java with no additional tools. Elsewhere, use the Send method or procedure of the library/controls/functions/whatever you acquired in Step 5.
And that's it. Check your inbox. You've got mail!
What to do with it?
Gee, I dunno... what do you want
to do with it? I know what I
wanted to do... print invoices and mail them. For VIC CRM
users this means that with the little expedient of installing GhostScript and MakePDF you'll be able to use an optional "Mail as PDF"
button in the Sales library to mail quotes and invoices as PDF attachments to your customers. One click - slick!