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, но он будет делать именно то, что вы хотите.