Does anyone know of a decent utility to print existing PDF files from VB? I need to batch print without user interaction and I need to be able to programatically control the paper size for each print. Lastly I don't want to deal with watched directories, I know which files need to be printed and can pass those to the utility doing the work.
I tried using DDE and Acrobat Reader - which works fine unless you need to have control over the paper sizes. Any suggestions are welcome. More background on what I'm up to below...
My customer has quite a few TIFF files that are mostly scans or e-prints of architectural drawings. They have business software that generates a list of files to print. I developed a utility to parse that list, find the files, and print them. It checks the physical size and resolution of each file to determine what paper size to use (there are about 5 different paper sizes possible). I used a 3rd party imaging library to make this easier on myself and it's been working fine. Now I need to duplicate this functionality for PDF files, which unfortunately my imaging library doesn't handle. So that's it in a nutshell.
Thanks for looking.
Last edited by Mothra; February 4th, 2008 at 06:49 PM.
Thanks but from what I read this just sounds like another PDF reader? I didn't see any mention of batch printing much less automating the process programatically. Are we looking at the same thing? I tried to open their user manual but it crashes Adobe every time! (a little ironic)
Have you tried open office? I know you can open PDF's and I am sure you can print them. Haven't tired to change page size/print size, but you can automate it.
AdobePDFSilent
Location
IAC/win/VBSamples/AdobePDFSilentVB
Description
This Visual Basic sample demonstrates how to silently print to the Adobe PDF printer. It processes files from a specified input directory (the default is the application's current directory) and places output PDF files in a specified output directory (the default is the current directory). If a valid directory is not specified, output is directed to My Documents. Output file names are created from the original file name with a .pdf extension.
The application uses Windows printing and can process file types for which there is a registered application, that is, Print appears on the file's context menu. Note that the application will try to process a file that has an associated application for opening the file even if it does not have a print process associated with it. That is, the file's context menu has an Open item but not a Print item. This may generate an unhandled exception. To manage such occurrences, there is an array of file types (file extensions) not to process. The array is initially set to ignore three file extensions: .dll, .exe and .pdf. Others may be added. Files for which an associated application cannot be found are skipped (not converted) without notice.
Because this application is dependent on Windows printing and specific registry entries, successful conversion of specific files, types and locations will vary from machine to machine and user to user. Careful testing should be done to ensure desired results can be achieved.
Usage
The application (AdobePDFSilent.exe) can be invoked from the command line. One or two arguments are required for automated use. If one argument is specified, it is used for both the Input and Output directory paths. If two arguments are included, the first is used to set the Input directory path and the second is used for the Output directory.
To prevent the created PDF documents from opening an Acrobat viewer, unselect the View Adobe PDF Results option in the Adobe PDF print driver printing preferences
Thanks David. I'm not actually wanting to print to PDF, I want to print existing PDF's to a network printer (which I can with DDE and Acrobat Reader). However I can't control the paper size that they print on which is the problem I'm facing now.
I will take a look at the Acrobat SDK just in case.
Option Explicit
Public glPid As Long
Public glHandle As Long
Public colHandle As New Collection
Public Const WM_CLOSE = &H10
Public Const WM_DESTROY = &H2
Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function GetParent Lib "User32" (ByVal hwnd As Long) As Long
Declare Function GetWindowThreadProcessId Lib "User32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function EnumWindows Lib "User32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation _
As String, ByVal lpFile As String, ByVal lpParameters _
As String, ByVal lpDirectory As String, ByVal nShowCmd _
As Long) As Long
Declare Function apiFindWindow Lib "User32" Alias "FindWindowA" _
(ByVal lpclassname As Any, ByVal lpCaption As Any) As Long
Function PrintPDFFile(str_PDFFile As String, strPrinter As String, optional strPaperSize As String = "acPRPSA4") As Boolean
' Prints PDF format (.pdf) files to a printer
On Error GoTo errTrap
Dim w_printer_short_name As String
Dim lngReturn As Long
Dim strFileName As String
Dim strPath As String
Dim strPrinterDefault As String
Dim prtloop As Printer
Dim bFound As Boolean
Dim i As Integer
PrintPDFFile = False
w_printer_short_name = get_printer_short_name(strPrinter)
strPrinterDefault = Application.Printer.DeviceName
i = 0
For Each prtloop In Application.Printers
If prtloop.DeviceName = w_printer_short_name Then
bFound = True
PrintPDFFile = bFound
Exit For
Else
i = i + 1
End If
Next prtloop
If Not bFound Then
PrintPDFFile = False
MsgBox "Cannot find specified printer - please contact IT", vbCritical, "Unknown Printer"
Exit Function
Else
Application.Printer = Application.Printers(w_printer_short_name)
End If
' **** set the paper size
application.Printer.PaperSize = strPaperSize
If g_AdobeCommand <> "C:\Program Files\Adobe\Acrobat\Acrobat.exe" Then
g_AdobeCommand = "C:\Program Files\Adobe\Acrobat\Acrobat.exe"
End If
Dim hwnd
hwnd = apiFindWindow("Adobe", "0")
lngReturn = Shell(g_AdobeCommand & " /t " & str_PDFFile & " " & w_printer_short_name, vbHide) ' vbMinimizedNoFocus)
' close adobe after sending file to the printer
cmdKill 5
PrintPDFFile = True
End If
Exit Function
ErrTrap:
Debug.Print Err.Description
Err.Clear
Resume Next
End Function
Private Sub cmdKill(ByVal nDelay As Integer)
Dim i As Long
' Wait for a few seconds to ensure the job has spooled to the printer
sleep_seconds (nDelay)
'
' Enumerate all parent windows for the process.
'
Call fEnumWindows
'
' Send a close command to each parent window.
' The app may issue a close confirmation dialog
' depending on how it handles the WM_CLOSE message.
'
For i = 1 To colHandle.Count
glHandle = colHandle.item(i)
Call SendMessage(glHandle, WM_CLOSE, 0&, 0&)
Next
End Sub
Public Function fEnumWindows() As Boolean
Dim hwnd As Long
'
' The EnumWindows function enumerates all top-level windows
' by passing the handle of each window, in turn, to an
' application-defined callback function. EnumWindows
' continues until the last top-level window is enumerated or
' the callback function returns FALSE.
'
Call EnumWindows(AddressOf fEnumWindowsCallBack, hwnd)
End Function
For my purpose an easy way was to use the component Adobe Acrobat 7.0 Browser Control Type Library (AcroPDF.dll) which seems to be part of Adobe Acrobat Reader.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.