Delphi: Как распечатать PDF, не показывая его? - PullRequest
15 голосов
/ 13 января 2010

Я некоторое время искал онлайн, но до сих пор не понял, как напечатать PDF-файл в Delphi, не показывая сам документ или диалоговое окно печати. Я просто хочу открыть файл, не показывая его, и распечатать его на принтере по умолчанию.

Я пытаюсь напечатать пакет документов PDF, и нет необходимости для вмешательства пользователя.

Ответы [ 4 ]

17 голосов
/ 13 января 2010

Существует несколько различных возможностей для печати 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) Или вы можете использовать стороннюю библиотеку ... Есть некоторые доступные, но не все они бесплатны

7 голосов
/ 13 января 2010

Вот несколько подпрограмм, которые я написал в своей библиотеке. Если вы передадите файл 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 из моей библиотеки ...

1 голос
/ 15 августа 2015

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

1 голос
/ 16 января 2012

Существует условно-бесплатная прога AutoPrint, которая отправляет все файлы в папке на принтер, стоит 35 долларов. (если у вас мало клиентов).

В противном случае было бы здорово, если бы кто-то мог исправить какой-то код, который делает то же самое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...