Delphi: Как распечатать PDF, не показывая его?
Я смотрю онлайн уже некоторое время, но я до сих пор не понял, как распечатать PDF файл в Delphi, не показывая сам документ или диалог печати. Я просто хочу открыть файл, не показывая его, и напечатать его на принтере по умолчанию.
Я пытаюсь распечатать пакет PDF-документов, и нет необходимости в вмешательства пользователя.
Ответы
Ответ 1
Есть несколько разных возможностей для печати PDF файлов... зависит от того, можете ли вы установить Adobe Reader для установки (я не знаю, хотите ли вы распространять свой инструмент или просто использовать его самостоятельно).
1) Можно загрузить элемент управления ActiveX в Adobe Reader и использовать его для печати
pdfFile.src := 'filename.pdf';
pdfFile.LoadFile('filename.pdf');
pdfFile.print;
2) Вы можете печатать PDF файлы с помощью самого Adobe Reader (может быть сделано с FoxIt тоже)
ShellExecute(0, 'open', 'acrord32', PChar('/p /h ' + FileName), nil, SW_HIDE);
3) Вы также можете использовать Ghostview и Ghostprint
ShellExecute(Handle, 'open', 'gsprint.exe', PChar('"' + filename + '"'), '', SW_HIDE);
4) Или вы можете использовать стороннюю библиотеку... Есть некоторые доступные, но не все из них бесплатны
Ответ 2
Вот несколько подпрограмм, которые я написал в своей библиотеке. Если вы передадите файл PDF в качестве параметра в PrintUsingShell, он должен распечататься, если установлена программа чтения Acrobat (может работать и с другим pdf-программным обеспечением, если они регистрируют себя в реестре).
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;
Примечание: попробуйте использовать их в своей версии Delphi и операционной системе (я разработал их в Delphi 7 и использовал их под Windows XP).
Если вы хотите иметь встроенную печать (без установки Acrobat Reader, но кто не установил Acrobat Reader в эти дни?), вы можете рассмотреть следующий набор компонентов: Pdft распечатать компоненты из WpCubed.
UPDATE
По запросу я добавил функцию Execute из моей библиотеки...
Ответ 3
Существует shareware-prog под названием "AutoPrint", который отправляет все файлы в папку на принтер,
стоимость 35 долларов. (если у вас не так много клиентов).
В противном случае было бы здорово, если бы кто-то мог исправить код, который делает то же самое.
Ответ 4
Печать PDF на принтер без попытки использования Adobe Reader из Delphi может быть выполнена с помощью Debenu Quick PDF Library, которая поддерживает все версии Delphi от 4 до XE8. Пример кода для печати PDF программно, не предварительно просмотрев его:
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;
Дополнительные параметры печати также доступны с помощью функций принтера клиента. Это не бесплатный SDK, но он будет делать именно то, что вы хотите.