2010-01-13 238 views
13

He estado buscando en línea desde hace un tiempo, pero todavía no he descubierto cómo imprimir un archivo PDF en Delphi sin mostrar el documento en sí, o un cuadro de diálogo de impresión. Solo quiero abrir un archivo sin mostrarlo e imprimirlo en la impresora predeterminada.Delphi: ¿Cómo imprimir un PDF sin mostrarlo?

Estoy tratando de imprimir un lote de documentos PDF, y no hay necesidad de interferencia del usuario.

Respuesta

15

Existen diferentes posibilidades para imprimir archivos PDF ... depende de si puede requerir la instalación de Adobe Reader (no sé si desea distribuir su herramienta o simplemente usarla usted mismo).

1) Es posible cargar el control ActiveX de Adobe Reader y utilizarlo para imprimir

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

2) Puede imprimir archivos PDF con la misma Adobe Reader (se podría hacer con FoxIt también)

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

3) también es posible usar Ghostview y Ghostprint

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

4) o puede utilizar en biblioteca partido hird ... Hay algunos disponibles, pero no todos ellos son libres

+0

Thx! No creo que pueda usar las soluciones de shell. El programa en el que estoy trabajando es un ERP hecho a medida y la impresión debe hacerse en el lado del cliente. Supongo que la primera opción requiere que el usuario tenga Adobe Reader instalado también. Las bibliotecas de terceros también son muy útiles, pero solo las pruebas son gratuitas :) Tendré que hablar con mi jefe, pero tenemos un presupuesto ajustado;) – Liezzzje

+0

Para la solución ActiveX se requerirá Adobe Reader también, sí ¿Pero cuáles son sus preocupaciones sobre la solución Shellexecute? Probablemente sea el método más barato ... – Leo

+0

¡Excelente! Recuerde agregar ShellApi, Windows a su cláusula uses. – JoeGalind

7

Aquí hay un montón de rutinas que he escrito en mi Libary. Si pasa un archivo pdf como parámetro al PrintUsingShell, debe imprimir si se ha instalado un programa Acrobat reader (podría funcionar también con otro software pdf si se registraron en el 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: por favor probar estos en su versión de sistema operativo y Delphi (los he desarrollado bajo Delphi 7 y los utilizó en Windows XP).

Si desea la impresión nativa (sin el lector Acrobat instalado, pero ¿quién no ha instalado Acrobat Reader actualmente?), Puede considerar el siguiente conjunto de componentes: Pdft print components from WpCubed.

ACTUALIZACIÓN

A petición que añade la función Ejecutar desde mi biblioteca ...

+0

Agradable. ¿De dónde viene la función "Ejecutar"? – neves

+0

@neves Como dije: este es el código de una enorme biblioteca de rutinas y clases de Delph que he escrito a lo largo de los años. Agregué el código 'Ejecutar' (que es código que probablemente ya tengas). – Edelcom

+0

@nevers, no olvides agregar @ + edelcom cuando comentes ... de lo contrario podría no ver tus comentarios (a menos que abriera este mensaje explícitamente, lo que hago ahora debido a tu voto positivo). – Edelcom

1

Hay un shareware-prog llamado 'AutoPrint' que envía todos los archivos de una carpeta a una impresora, cuesta 35 dólares. (si no tienes muchos clientes).

De lo contrario, sería genial si alguien pudiera arreglar algún código que haga lo mismo.

+2

¿Puedes editar tu respuesta para incluir un enlace al programa relevante? ¿Podría también agregar algo de información sobre su uso de esto y si funciona según lo previsto? –

1

Imprimir un PDF en una impresora sin intentar usar Adobe Reader desde Delphi se puede hacer usando Debenu Quick PDF Library, que admite todas las versiones de Delphi de 4 a XE8.Código de ejemplo para imprimir un archivo PDF mediante programación sin la vista previa en primer lugar:

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; 

Más opciones avanzadas de impresión también están disponibles mediante el customer printer functions. No es un SDK gratuito, pero hará exactamente lo que quieras.

+0

O utilice la biblioteca Delphi Pdfium – MartynA

Cuestiones relacionadas