2010-01-13 26 views
13

Ho cercato online da qualche tempo, ma non ho ancora capito come stampare un file PDF in Delphi senza mostrare il documento stesso o una finestra di dialogo di stampa. Voglio solo aprire un file senza mostrarlo e stamparlo sulla stampante predefinita.Delphi: come stampare un PDF senza mostrarlo?

Sto tentando di stampare un batch di documenti PDF e non sono necessarie interferenze dell'utente.

risposta

15

Esistono diverse possibilità per stampare i PDF ... dipende se è possibile richiedere l'installazione di Adobe Reader (non so se si desidera distribuire il proprio strumento o semplicemente utilizzarlo da soli).

1) E 'possibile caricare il controllo ActiveX di Adobe Reader e utilizzarlo per la stampa

pdfFile.src := 'filename.pdf'; 
pdfFile.LoadFile('filename.pdf'); 
pdfFile.print; 

2) È possibile stampare i file PDF con Adobe Reader stesso (potrebbe essere fatto con Foxit troppo)

ShellExecute(0, 'open', 'acrord32', PChar('/p /h ' + FileName), nil, SW_HIDE); 

3) si potrebbe anche usare Ghostview e Ghostprint

ShellExecute(Handle, 'open', 'gsprint.exe', PChar('"' + filename + '"'), '', SW_HIDE); 

4) o si può utilizzare a libreria di partito Hird ... Ci sono alcuni disponibili, ma non tutti sono liberi

+0

Thx! Non penso di poter usare le soluzioni di shell. Il programma su cui sto lavorando è un ERP personalizzato e la stampa deve essere eseguita sul lato client. Suppongo che la prima opzione richieda all'utente di installare anche Adobe Reader? Anche le librerie di terze parti sono molto utili, ma solo le prove sono ovviamente gratuite :) Dovrò parlare con il mio capo, ma abbiamo un budget limitato;) – Liezzzje

+0

Per la soluzione ActiveX Adobe Reader non è richiesto pure, si. Ma quali sono le tue preoccupazioni riguardo alla soluzione Shellexecute? Probabilmente sarebbe il metodo più economico ... – Leo

+0

Eccellente! Ricordarsi di aggiungere ShellApi, Windows alla clausola use. – JoeGalind

7

Qui ci sono un sacco di routine ho scritto nel mio libary. Se si passa un file pdf come parametro a PrintUsingShell, è necessario stampare se è stato installato un programma Acrobat Reader (potrebbe funzionare anche con altri software PDF se si sono registrati nel registro).

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; 

Nota: si prega di provare questi alla versione e sistema operativo Delphi (li ho sviluppato sotto Delphi 7 e li ha utilizzati in Windows XP).

Se si desidera stampare nativamente (senza Acrobat Reader installato, ma chi non ha installato Acrobat Reader al giorno d'oggi?) Si potrebbe prendere in considerazione il seguente set di componenti: Pdft print components from WpCubed.

UPDATE

Su richiesta ho aggiunto la funzione Execute dalla mia biblioteca ...

+0

Bello. Da dove viene la funzione "Esegui"? – neves

+0

@neves Come detto: questo è il codice di una massiccia libreria di routine Delphi e classi che ho scritto io stesso nel corso degli anni. Ho aggiunto il codice 'Esegui' (che probabilmente è il codice che hai già). – Edelcom

+0

@nevers, non dimenticarti di aggiungere @ + edelcom quando commenti ... altrimenti potrei non vedere i tuoi commenti (a meno che non apro esplicitamente questo messaggio, cosa che ho fatto a causa della tua upvote). – Edelcom

1

C'è uno shareware-prog chiamato 'AutoPrint' che invia tutti i file in una cartella a una stampante, costano 35 dollari. (se non hai molti clienti).

Altrimenti sarebbe bello se qualcuno potesse correggere un codice che faccia lo stesso.

+2

Puoi modificare la tua risposta per includere un link al programma in questione? Potresti anche aggiungere alcune informazioni sul tuo utilizzo di questo e se funziona come previsto? –

1

È possibile stampare un PDF su una stampante senza utilizzare Adobe Reader di Delphi utilizzando Debenu Quick PDF Library, che supporta tutte le versioni di Delphi da 4 a XE8.Codice di esempio per la stampa di un file PDF a livello di codice, senza l'anteprima prima:

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; 

Più opzioni di stampa avanzate sono disponibili utilizzando il customer printer functions anche. Non è un SDK gratuito, ma farà esattamente quello che vuoi.

+0

Oppure utilizzare la libreria Delphi Pdfium – MartynA

Problemi correlati