Moin allerseits!
Dieses Tutorial bezieht sich auf die Erstellung von Pdf Dateien mit Ghostscript & Co.
Um es gleich vorweg zu nehmen:
Nein, ich kenne keine Möglichkeit Pdfs ohne GS zu erstellen.
Es gibt noch die Möglichkeit Pdfs mit freien Komponenten zu erstellen (Nishita usw.) die sind aber so einfach gestrickt, dass sie meiner Erfahrung nach nicht einmal für den Hausgebrauch reichen. Anders sieht es mit den kostenpflichtigen Komponenten wie WPDF o.ä aus. Aber die kosten halt Geld...
1. Was braucht man?
- Ghostscript muss installiert sein. (unumgänglich)
- FreePdf (es gibt auch einen Weg das direkt mit GS zu machen –
ich krieg es bloss nicht hin – mehr dazu später...
- Einen installierten PostScript Drucker.
- Die Delphi Quelle von TPrinter.
2. Post Script Dateien erzeugen
Die Idee ist eine PostScript Datei zu erzeugen und die mit FreePdf bzw. GS zu destillieren.
Dazu muss man erstmal einen Weg finden direkt in eine PS Datei zu drucken ohne dass der Drucker Dialog aufgeht und einem nach einem Speicherort fragt. Die Lösung findet sich hier im Forum und stammt von Tino. Leider muss hierfür die Quelle von TPrinter erweitert werden:
www.delphi-forum.de/viewtopic.php?t=11003
1. Ein weiteres Property dem tPrinter Objekt hinzufügen:
Delphi-Quelltext
1: 2: 3: 4:
| private fOutputFile: String Public Property OutputFile: String read fOutputFile write fOutputFile; |
2. In der Procedure BeginDoc werden dem DocInfo-Record einige Werte zugewiesen. Dort wird das o. g. neue Property hinzugefügt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| with DocInfo do begin cbSize := SizeOf(DocInfo); lpszDocName := PChar(Title); lpszOutput := PChar(fOutputFile); end; |
So, nun kann man direkt in eine Datei drucken und wenn man einen PS Drucker installiert hat sind die Dateien auch von GS destillierbar! Ein geeigneter Drucker ist z.B.
Apple LaserWriter II NT v47.0. An dieser Stelle wäre es schön zu wissen wie man einen Drucker automatisch installiert oder noch besser wie man ihn temporär installiert. Wenn mir das jemand verraten könnte wäre ich SEHR DANKBAR!
So erzeugt man dann eine PS Datei:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| function CreatePS(const psPath, psPrinter: string): boolean; var i: integer; begin Result := true; try with Printer do begin for i:=0 to Printers.Count -1 do if Printers[i] = psPrinter then begin PrinterIndex := i; break; end; OutputFile:= psPath; BeginDoc; Canvas.Malwas... Canvas.Schreibwas... Canvas.blabla... EndDoc; end; except Result := false; end; end; |
3. PS Datei destillieren
Nun ist die PS Datei vorhanden und muss noch von GS destilliert werden. GS hat dafür eigentlich Batchdateien z.B. ps2pdf.bat - leider bin ich zu blöd die zu benutzen. Wenn jemand weiß wie das geht – immer her damit!
Na ja, da ich offensichtlich zu blöd bin (oder mein GS nicht richtig installiert ist?) habe ich es dann mit FreePdf gelöst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| procedure Distill(psPath: string); var SInfo: TStartupInfo; PInfo: TProcessInformation; Reg: TRegistry; Cmd, fpPath: string; begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey('\Software\shbox\FreePdfXP',False); fpPath := Reg.ReadString('fpDir'); fpPath := fpPath + 'freepdf.exe'; Reg.Free; Cmd := '"' + fpPath + '" ' + psPath + ' /a /x'; FillChar(SInfo, SizeOf(SInfo), #0); with SInfo do begin cb := SizeOf(SInfo); dwFlags := STARTF_USESHOWWINDOW; wShowWindow := SW_HIDE; end; if CreateProcess(nil, PChar(Cmd), nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(fpPath)), SInfo,PInfo) then WaitForSingleObject(PInfo.hProcess, INFINITE); DeleteFile(psPath); end; |
FreePdf erzeugt in dem Beispiel eine Pdf- Datei in dem Verzeichnis in dem die PS- Datei steht mit dem Namen der PS- Datei – also aus C:\Test.ps wird C:\Test.pdf
So viel dazu. Ich hoffe, dass der ein oder andere noch Ideen hat wie man das ganze optimieren könnte.
MfG Schelm