Reputation: 430
I have been looking online for some time now, but I still haven't figured out how to print a PDF file in Delphi without showing the document itself, or a print dialog. I just want to open a file without showing it, and print it to the default printer.
I'm trying to print a batch of PDF documents, and there is no need for user interference.
Upvotes: 16
Views: 44133
Reputation: 13
I came here initially because I was thinking of doing what the OP was wanting, to print from a Delphi app. Someone else suggested an alternative solution, an inexpensive commercial app, called AutoPrint. But the previous person gave little information. So, I googled it and found it. I would have just added a comment to the other answer but I don't have enough points to comment on another answer, so I'm adding my own answer.
The product is called AutoPrint by 4-Tech-Engineering:
https://4-tech-engineering.com/
I have no connection to the company, I just found their solution easier than rewritting the wheel. It is free to try, $35 for Standard and $85 for Pro. It can print a lot of different kinds of files, but I mainly wanted PDF printing which it of course does.
Upvotes: 1
Reputation: 2430
Printing a PDF to a printer without attempting to use Adobe Reader from Delphi can be done using Debenu Quick PDF Library, which supports all versions of Delphi from 4 to XE8. Sample code for printing a PDF programmatically without previewing it first:
procedure TForm6.PrintDocumentClick(Sender: TObject);
var
iPrintOptions: Integer;
begin
DPL := TDebenuPDFLibrary1115.Create;
try
UnlockResult := DPL.UnlockKey('...'); // Add trial license key here
if UnlockResult = 1 then
begin
// Load your file
DPL.LoadFromFile('test.pdf', '');
// Configure print options
iPrintOptions := DPL.PrintOptions(0, 0, 'Printing Sample');
// Print the current document to the default printing
// using the options as configured above
DPL.PrintDocument(DPL.GetDefaultPrinterName(), 1, 1, iPrintOptions);
end;
finally
DPL.Free;
end;
end;
More advanced printing options are also available using the customer printer functions. It's not a free SDK, but it will do exactly what you want.
Upvotes: 1
Reputation: 11
There is a shareware-prog called 'AutoPrint' that sends all files in a folder to a printer, cost 35 dollar. (if u dont have many customers).
Otherwise it would be cool if someone could fix some code that does the same.
Upvotes: 1
Reputation: 5058
Here are a bunch of routines I have written in my libary. If you pass a pdf file as parameter to PrintUsingShell it should print if a Acrobat reader program has been installed (might work with other pdf-software too if they registered themselfs in the registry).
PrintUsingShell( x );
procedure PrintUsingShell( psFileName :string);
var s : string;
i : integer;
begin
if not FileExists(psFileName)
then
Exit;
s := FindShellPrintCmd( ExtractFileExt(psFileName) );
i := Pos('%1',s);
if i > 0
then begin
System.Delete(s,i,2);
System.Insert(psFileName,s,i);
Execute(s);
end;
end;
function FindShellCmd(psExtension:string;psCmd:string): string;
var r : TRegistry;
sName : string;
begin
psExtension := Trim(psExtension);
if psExtension = ''
then begin
Result := '';
Exit;
end;
psCmd := Trim(psCmd);
if psCmd = ''
then
psCmd := 'OPEN'
else
psCmd := UpperCase(psCmd);
if psExtension[1] <> '.'
then
psExtension := '.' + psExtension;
r := TRegistry.Create(KEY_READ);
try
r.RootKey := HKEY_LOCAL_MACHINE;
r.OpenKeyReadOnly('software\classes\' + psExtension);
sName := r.ReadString('');
r.CloseKey();
r.OpenKeyReadOnly('software\classes\' + sName + '\Shell\' + psCmd + '\Command');
Result := r.ReadString('');
r.CloseKey();
finally
FreeAndNil(r);
end;
end;
function FindShellOpenCmd(psExtension:string):string;
begin
Result := FindShellCmd(psExtension,'OPEN');
end;
function FindShellPrintCmd(psExtension:string):string;
begin
Result := FindShellCmd(psExtension,'PRINT');
end;
{$ifdef windows}
function LocalExecute( psExeName:string ; wait:boolean ; how:word):word;
var i : integer;
prog,parm:string;
msg:TMsg;
rc : word;
begin
i := pos(psExeName,' ');
if i = 0
then begin
prog := psExeName;
parm := '';
end
else begin
prog := copy( psExeName,1,i-1);
parm := copy( psExeName,i+1,255);
end;
if pos(prog,'.') <> 0
then
prog := prog + '.exe';
psExeName := prog + ' ' + parm + #0;
rc := WinExec( @psExeName[1] , how );
if wait
then begin
if (rc > 32)
then begin
repeat
if PeekMessage(Msg,0,0,0,PM_REMOVE)
then begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until (GetModuleUsage(rc) = 0)
end;
end;
end; { LocalExecute }
{$endif}
{$ifdef win32}
function LocalExecute32(FileName:String; Wait:boolean; Visibility : integer;
lWaitFor:Cardinal=INFINITE):integer;
var zAppName:array[0..512] of char;
zCurDir:array[0..255] of char;
WorkDir:String;
StartupInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
begin
StrPCopy(zAppName,FileName);
GetDir(0,WorkDir);
StrPCopy(zCurDir,WorkDir);
FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) { pointer to PROCESS_INF }
then Result := -1
else begin
if Wait
then begin
Result := WaitforSingleObject(ProcessInfo.hProcess,lWaitFor);
GetExitCodeProcess(ProcessInfo.hProcess,LongWord(Result));
end;
end;
end;
{$endif}
function Execute( psExeName:string):integer;
begin
{$ifdef windows} result := LocalExecute(psExeName, false , SW_SHOW); {$endif}
{$ifdef win32} result := LocalExecute32(psExeName, false , SW_SHOW); {$endif}
end;
Note: please try these out on your Delphi version and Operating system (I have developed them under Delphi 7 and used them under Windows XP).
If you want native printing (without Acrobat reader installed - but who hasn't installed Acrobat Reader these days?) you might consider the following component set: Pdft print components from WpCubed.
UPDATE
Upon request I added the Execute function from my library ...
Upvotes: 7
Reputation: 38190
There are some different possibilities to print PDFs... it depends whether you can require Adobe Reader to be installed (I don't know if you want to distribute your tool or just use it yourself).
1) It is possible to load the ActiveX control of Adobe Reader and use it for printing
pdfFile.src := 'filename.pdf';
pdfFile.LoadFile('filename.pdf');
pdfFile.print;
2) You can print PDFs with Adobe Reader itself (could be done with FoxIt too)
ShellExecute(0, 'open', 'acrord32', PChar('/p /h ' + FileName), nil, SW_HIDE);
3) You could also use Ghostview and Ghostprint
ShellExecute(Handle, 'open', 'gsprint.exe', PChar('"' + filename + '"'), '', SW_HIDE);
4) Or you could use a third party library... There are some available, but not all of them are free
Upvotes: 18