Newsgroup: it.comp.lang.delphi
Titolo: [Delphi 7 ] PdfCreator

Ciao a tutti,
 
dato che mio cognato ha deciso di inviare le mail con allegato un report in formato pdf ho deciso di affidarmi a PDFCreator, sono riuscito ( tramite codice ) a creare i pdf, solo che non riesco a trasformare il codice per testare se PDFCreator ha terminato la stampa dei report. Negli esempi proposti ho trovato codice vbscript ma non riesco a capire come trasformarlo in delphi, qui di seguito il codice :
 
' Testpage2PDF.vbs script
' Part of PDFCreator
' License: GPL
' Homepage: 
http://www.pdfforge.org/products/pdfcreator
 
' Windows Scripting Host version: 5.1
' Version: 1.0.0.0
' Date: September, 1. 2005
' Author: Frank Heindörfer
' Comments: Save the test page as pdf-file using
'           the com interface of PDFCreator.
 
Option Explicit
 
Const maxTime = 10    ' in seconds
Const sleepTime = 250 ' in milliseconds
 
Dim fso, WshShell, PDFCreator, DefaultPrinter, ReadyState, c, _
 AppTitle, Scriptname, Scriptbasename
 
Set fso = CreateObject("Scripting.FileSystemObject")
 
ScriptBaseName = fso.GetBaseName(Wscript.ScriptFullname)
 
AppTitle = "PDFCreator - " & ScriptBaseName
 
If CDbl(Replace(WScript.Version,".",",")) < 5.1 then
 MsgBox "You need the ""Windows Scripting Host version 5.1"" or greater!", vbCritical + vbSystemModal, AppTitle
 Wscript.Quit
End if
 
Set WshShell = WScript.CreateObject("WScript.Shell")
 
Set PDFCreator = Wscript.CreateObject("PDFCreator.clsPDFCreator", "PDFCreator_")
PDFCreator.cStart "/NoProcessingAtStartup"
 
ReadyState = 0
With PDFCreator
 .cOption("UseAutosave") = 1
 .cOption("UseAutosaveDirectory") = 1
 .cOption("AutosaveDirectory") = fso.GetParentFolderName(Wscript.ScriptFullname)
 .cOption("AutosaveFilename") = "Testpage - PDFCreator"
 .cOption("AutosaveFormat") = 0                            ' 0 = PDF
 DefaultPrinter = .cDefaultprinter
 .cDefaultprinter = "PDFCreator"
 .cClearcache
 .cPrintPDFCreatorTestpage
 .cPrinterStop = false
End With
 
c = 0
 
Do While (ReadyState = 0) and (c < (maxTime * 1000 / sleepTime))
 c = c + 1
 Wscript.Sleep sleepTime
Loop
 
With PDFCreator
 .cDefaultprinter = DefaultPrinter
 WScript.Sleep 200
 .cClose
End With
 
If ReadyState = 0 then
 MsgBox "Creating test page as pdf." & vbcrlf & vbcrlf & _
  "An error is occured: Time is up!", vbExclamation + vbSystemModal, AppTitle
End If
 
'--- PDFCreator events ---
 
Public Sub PDFCreator_eReady()
 ReadyState = 1
End Sub
 
Public Sub PDFCreator_eError()
 MsgBox "An error is occured!" & vbcrlf & vbcrlf & _
  "Error [" & PDFCreator.cErrorDetail("Number") & "]: " & PDFcreator.cErrorDetail("Description"), vbCritical + vbSystemModal, AppTitle
 Wscript.Quit
End Sub
 
La prima parte sono riuscito a portarla il delphi, infatti la creazione dei report funziona, invece la parte dove testa la variabile ReadyState con conseguente richiamo alla procedura PDFCreator_eReady() non riesco a farlo.
 
A dimenticavo, la versione di PDFCreator è la 1.7.3
 
Un grazie anticipato a tutti.
 
Ciao da Enrico Giudici c/o Icograf

 dato che mio cognato ha deciso di inviare le mail con allegato un report in formato pdf ho deciso di affidarmi a PDFCreator, sono riuscito ( tramite codice ) a creare i pdf, solo che non riesco a trasformare il codice per testare se PDFCreator ha terminato la stampa dei report. Negli esempi proposti ho trovato codice vbscript ma non riesco a capire come trasformarlo in delphi, qui di seguito il codice [...]
 
Ciao Enrico, sei riuscito a scrivere almeno una parte del codice?
 
Magari postala così potremmo iniziare ad analizzare quella e vedere come completarla, giusto per capire qual è la parte specifica dello script che non riesci a codificare e/o a fare funzionare.
 
Ciao,
  Marco.
 
-- 
MARCO BREVEGLIERI (Software and Web Developer)
#Home: 
http://bit.ly/marcobreveglieri
 
#Blog: 
http://bit.ly/compilaquindiva
 

 
Scusami Marco ma ho fatto un pò di casino nel rispondere, ti ho mandato la risposta in privato, non era nelle mie intenzioni.
 
ci riprovo.
 
Qui di seguito il mio codice funzionante per la creazione dei PDF.
 
    // inizializzazione
    PDFCreator := CreateOLEObject('PDFCreator.clsPDFCreator');
    PDFCreator.cStart('/NoProcessingAtStartup');
    PDFCreator.cOption('AutosaveDirectory') := 'C:\ICOGRAF\MAIL';
    PDFCreator.cOption('UseAutosave') := 1;
    PDFCreator.cOption('UseAutosaveDirectory') := 1;
    PDFCreator.cOption('AutoSaveFormat') := 0;
 
    // setto la stampante di PDFCreator
    Printer.SetPrinter(pchar('PDFCreator'),nil,nil,0);
 
    // stampo il report
    ........
    ........
 
    printJobCount := PDFCreator.cCountOfPrintJobs;
 
    /// Tell PDFCreator we're done printing pages.
    PDFCreator.cPrinterStop := false;
 
    // le righe seguenti dovrebbero servire a capire se PDFCreator
    // ha terminato la creazione dei PDF
    // tale codice l'ho trovato in rete ma per la versione 0.9.9
    while(PDFCreator.cCountOfPrintjobs <> 0) do
         Application.ProcessMessages;
 
    ///   now wait for PDFCreator to finish
    c := PDFCreator.cCountOfPrintJobs;
    while c > printJobCount do
       begin
          Sleep(5);
          Application.ProcessMessages;
          c := PDFCreator.cCountOfPrintJobs;
       end;
 
   // fine report
   PDFCreator.cclose;
   VarClear(PDFCreator);
 
Io vorrei utilizzare il codice che ho postato all'inizio, praticamente quello gestito dalla variabile ReadyState, il problema è che non so come creare/gestire le due procedure e_ready ed error.
 
Spero di essere stato abbastanza chiaro.
 
Un grazie sentito da Enrico Giudici c/o Icograf

 formato pdf ho deciso di affidarmi a PDFCreator
 
 
Per curiosita', xche questa soluzione e non un tool di reportistica?
Molti di essi prevedno già la genrazione di un report e il suo salvataggio in formato pdf (ma non solo..)?
 
 
A.

 trasformarlo in delphi, qui di seguito il codice :
 
Se stai usando delphi e anche il report lo generi con quickreport non 
dovresti avere problemi.
Quickreport ha un componente (non visual) per "trasformare" il tuo report in 
file .pdf ma, se come nel mio caso, il rusultato non dovesse soddisfarti 
puoi sempre usare lo spezzone di codice che riporto (comunque trovabile con 
google ricercando "delphi quickreport pdf")
 
procedure TFDVB.ExportAsPdf;
var  Pdf: TPdfDocument;
       aMeta: TMetaFile;
       i: integer;
begin
  Pdf := TPdfDocument.Create;
  try
    Pdf.DefaultPaperSize := psA4;
    Qrp1.Prepare;
    for i := 1 to Qrp1.QRPrinter.PageCount do begin
      Pdf.AddPage;
      aMeta := Qrp1.QRPrinter.GetPage(i);
      try
        // draw the page content
        Pdf.Canvas.RenderMetaFile(aMeta,1,0,0);
      finally
        FreeAndNil(aMeta);
      end;
    end;
    Pdf.SaveToFile(PDFFieName);
  finally
    FreeAndNil(Pdf);
  end;
end;
 
Per poter utilizzare questa procedura si deve inserire nelle uses la unit 
SynPdf che e' gratuita e la puoi scaricare al seguente indirizzo
http://synopse.info/files/pdf/synpdf.zip
 
 
Questa procedura crea un file .pdf, se poi prima di inviarlo per email lo 
vuoi vedere (tipo preview) allora suggerisco le librerie della Gnostice 
PdfToolkit.
Questo tool (per niente economico) permette molte operazioni sui file .pdf, 
quello della visualizzazione e' banale (nel senso che visualizza solo) ma 
puoi anche modificare i pdf, tagliarli,
incrementarli, unirli, eliminare/aggiungere immagini ecc... ecc... tutto 
demnro delphi senza file esterni (nel mio caso ha risolto molto).
 
Spero di esseri stato utile.
 
Ciao
 
Daniele
 

> Qrp1.QRPrinter.PageCount
 
Non so adesso, ma le vecchie versioni di qr per fare questa cosa generavano tutto il report, per poi rigenerarlo in fase di stampa.
 
Magari ora non è più così..
In caso contrario, se hai report piccoli, ok, ma se il tuo report è grosso buonanotte.
 
A.

 Molti di essi prevedno già la genrazione di un report e il suo salvataggio in formato pdf (ma non solo..)?
 
Ciao Alberto,
 
io utilizzo ancora Delphi 7 con il quick report contenuto all'interno, tra parentesi non so nenache che versione sia dato che utilizzo freereport per la reportistica, e, da quanto ne so freereport non esporta in pdf.
 
Ciao da Enrico e.. speriamo di vederci presto.


Ciao Daniele,
non sei stato utile ma... UTILISSIMO !!!
 
Tieni presente che per stampare il report utilizzo FreeReport, QuickReport non l'ho mai utilizzato, al limite proverò il tuo codice solo per questa funzionalità di avere i pdf. Domanda, ma il tuo codice funziona anche con la versione di QuickReport contenuta nel mio Delphi 7 ? Tieni presente che non ho mai aggiornato QuickReport dato che non lo utilizzo.
 
Ciao e grazie ancora per il tuo utilissimo supporto.

 In caso contrario, se hai report piccoli, ok, ma se il tuo report è grosso buonanotte.
 
No, è un semplice report, a dire la verità sono 2, il primo di una pagina mentre il secondo può avere anche più pagine.
 
Ciao e grazie da Enrico.

Ciao
sempre con synpdf avevo aggiunto al buon vecchio fuzzyreport la possibilita' di espotare in pdf:
 
procedure TStandardPreview.ExportPDF;
var
  X: Integer;
  OldDir: String;
  xPDF: TPdfDocumentGDI;
begin
  OldDir := GetCurrentDir;
  with SaveDialog do
  begin
    Filter := 'Portable Data Format (*.pdf)|*.pdf';
    FileName := Report.Title;
    FilterIndex := 0;
    if Execute then
    begin
      Application.ProcessMessages;
      xPDF := TPdfDocumentGDI.Create;
      xPDF.Info.Creator := 'Fuzzy Report';
      xPDF.Info.Author := Application.Title;
      xPDF.Info.Title := Report.Title;
      xPDF.Info.Subject := Report.Title;
      xPDF.Info.CreationDate := Now;
      try
        for X := 0 to Report.EMFPages.Count -1 do
        begin
          xPDF.AddPage;
          with xPDF.VCLCanvas do Draw(0, 0, Report.EMFPages[X].Pict);
        end;
 
        if Pos('.PDF',UpperCase(FileName))<>Length(FileName)-3 then
          xPDF.SaveToFile (FileName + '.pdf')
        else
          xPDF.SaveToFile (FileName)
      finally
        xPDF.Free;
      end;
    end;
  end;
  SetCurrentDir (OldDir);
end;
 
Quindi penso che si possa aggiungere in freereport allo stesso modo visto che molto del codice e' simile.
 
Giovanni

 che non ho mai aggiornato QuickReport dato che non lo utilizzo.
 
Dato che la funzione si appoggia sul componente di quickreport non dovrebbe 
dipendere dalle versioni, nel mio caso e' stata utilizzata su delphi 6, xe, 
xe2/5.
 
Tieni anche presente l'alert di Alberto perche' per fare questa esportazione 
PRIMA generi il report (sempre nel mio caso i miei report sono banalissimi 
di norma generano al massimo 3-4 pagine, quindi sono veloci).
 
Nella versione 5 di quickreport ci sarebbe la possibilita' di creare un pdf 
dal report ma al momento non riesco ad usarlo mi da degli errori strani, al 
momento non posso essere piu' preciso sulla natura di questi errori perche' 
(sbagliando in quanto non approfondisco) finche' regge l'altra procedura 
continuero' ad usarla.
 
Un saluto a tutti
 
Ciao
 
Daniele 
 

> Tieni anche presente l'alert di Alberto perche' per fare questa esportazione 
 
Sono anni che non uso qr.
Un modo per capire se fa ancora quello che dico oppure no è semplice.
Basta definire un report, associare qualcosa ad un evento alzato ad ogni generazione di pagina e metterci un breakpoint.
 
A.
 

 generazione di pagina e metterci un breakpoint.
Per (s)fortuna prima di esportare in pdf si deve fare tutto il report, poi 
qr si crea i necessari metafile e dai metafile si porta in pdf con la 
synpdf.
Potrebbe sembrare un po troppo laborioso ...
 
Appena ho un po di tempo provo a vedere se hanno cambiato qualcosa con il 
filtro pdf.
 
ciao
 
Daniele 
 

 for i := 1 to Qrp1.QRPrinter.PageCount do begin 
 
SE, PER **CALCOLARE IL NUMERO TOTALE DI PAGINE**, ti genera il report una prima volta, e poi ti genera il report UNA SECONDA VOLTA PER STAMPARLO, puoi anche tapparti il naso, se il report è piccolo.
Ma se il tuo report ha 5000 pagine (no: non è una esagerazione  ma un caso reale) e lui fa il lavoro 2 VOLTE, sono uccelli per i diabetici.
 
A.

 continuero' ad usarla.
purtroppo ho la 3.0.9 e per il momento non ho nessuna necessità di aggiornarlo dato che per i miei report mi trovo benissimo con FreeReport.
 
Un grazie ancora per il tuo supporto.
 
Ciao da Enrico.

 filtro pdf.
 
ma questo filtro è reperibile da qualche parte ?


 Ma se il tuo report ha 5000 pagine (no: non è una esagerazione  ma un caso reale) e lui fa il lavoro 2 VOLTE, sono uccelli per i diabetici.
 
:-))) sei sempre il solito burlone ;-)
 
Ciao da Enrico.

> :-))) sei sempre il solito burlone ;-)
 
per gli uccelli o per le 5000 pagine??? Lol! :-D
 
 
A.
 

> per gli uccelli o per le 5000 pagine??? Lol! :-D
 
per le tue mitiche esternazioni ;-D
 
Ciao da Enrico.

Io preferirei utilizzare PDFCreator visto che sono riuscito a farlo funzionare, mi manca solo come fare per sapere se il processo di stampa è terminato, il codice che ho postato non funziona con la versione nuova. Negli esempi inclusi con il pacchetto non è presente Delphi ma java, dot-net, vb-script, etc. Dal codice vb script ho visto che PdfCreator richiama due procedure, eReady ed Error, ma tali funzioni non sono definite per cui non ho la più pallida idea di come farlo in Delphi. Inoltre, SynPDF va benissimo ( devo ancora provarlo ) ma al contrario di PDFCreator ha un passaggio in più. Sto anche guardando PowerPDF che è tipo QuickReport, ma la prima soluzione per me sarebbe il non plus-ultra.
 
Ciao a tutti per il supporto da Enrico.

 
 
"Alberto Salvati"  ha scritto nel messaggio 
news:07940720-35e9-4af4...@googlegroups.com...

Super limite di qr, anche con l'ultima versione (io ho la 5.05, ma sembra ce 
ne sia una nuova).
Purtroppo non c'e' via di uscita con questo tool !
 
Invece con quelli che usi tu e' piu' snello ?
 
Ciao
 
Daniele 
 

Ciao,
 
qr.prepare si chiama (quasi) solo per generare un report invisibile per 
ottenere il numero totale delle pagine.
questo se ti serve mettere da qualche parte una label con "pag. 01 di 31"; 
in altre parole per capire che hai 31 pagine da stampare.
 
Dopo rigeneri un secondo report (uguale al primo) ma ora sai quante pagine 
deve stampare (lavoro inutile ma con qr si fa cosi).
 
Per quanto riguarda il tuo caso, se freereport (che non conosco) prepara le 
stampe e le "stocca" in metafile, allora puoi trasformarle in pdf in quanto
il metafile e' tale a prescindere da chi lo crea.
 
aMeta := Qrp1.QRPrinter.GetPage(i);
 
Penso che fr abbia qualcosa del genere.
 
Ciao
 
Daniele
 

 Penso che fr abbia qualcosa del genere.
 
credo anch'io che dovrebbe gestire una cosa del genere, proviamo, anche se ti dicevo avrei preferito gestire il tutto con PDFCreator visto che avevo predisposto il codice opportuno. Con la soluzione che mi prospetti tu speriamo di non rallentare la generazione del pdf, di solito non sono molte pagine ma se fossero molte ?
 
Ciao e grazie ancora da Enrico.

 generazione del pdf, di solito non sono molte pagine ma se fossero molte ?
 
Non so cosa dirti, comunque per darti una linea di paragone con il programma 
che uso per la stampa di fine anno preparo 14 pagine con qr.
la prima e' di presentazione, l'ultima di riepilogo e 12 sono il resoconto 
mensile del lavoro giornaliero svolto in ogni mese.
Per ogni giorno si interrogano 3 db dove si prendono i vari campi e si fanno 
le operazioni opportune (per esempio i parziali, i totali , i netti, lordi e 
cosi' via ... lo so e' un po vago ma e' per dare un'idea).
Il risultato e', di solito, un file pdf (estratto con la procedura 
precedente) di 14 pagine (ma se ci sono note integrative possono essere 
anche di piu') che viene generato, come si diceva 2 volte, la prima per 
sapere quante pagine ci sono e la seconda per la stampa vera e propria.
Il file pdf cosi' creato e' visulaizzato in un pdfviewer della gnostice 
dopo, circa, 1-2 secondi su un intel i5 2400 3.1 ghz conpilato con xe 2 (per 
me e' un risultato accettabile).
 
Ciao
 
Daniele 
 

 me e' un risultato accettabile).
 
sono d'accordo con te.
 
Ciao e ancora grazie 1000.
 
Enrico.