Compago

...free knowledge

 
  • Increase font size
  • Default font size
  • Decrease font size
Home Manuali Programmazione Stampare con Delphi

Stampare con Delphi

E-mail Stampa PDF

Alcuni componenti potrebbero includere già un metodo per stampare il proprio contenuto, come accade per esempio con il componente  TRichEdit che utilizza direttamente il suo metodo print:

RichEdit1.Print('Prova stampa');

In generale però questo non accade e quindi per stampare con Delphi occorre usare le funzioni della unit Printers.

Il metodo più veloce per stampare un testo è quello di ricorrere alla funzione AssignPrn, la quale assegna un file di testo alla stampante di default. Una volta assegnato il file sarà possibile scriverci dentro come un qualsiasi altro file di testo, solo che l'output sarà inviato alla stampante.

uses
  ...
  Printers,
  ...
procedure ProvaStampa;
var
F: TextFile;
begin
  AssignPrn(F); { assegna il file di testo alla stampante }
 try
  Rewrite(F); { Occorre usare Rewrite dopo aver usato AssignPrn }
  WriteLn(F, 'Prova di stampa da Delphi.');
  WriteLn(F, 'Seconda riga.');
 finally
   CloseFile(F);
 end;
end;
 

Come è possibile notare questa tecnica è molto semplice, ma non è stato possibile scegliere una stampante, ne impostare le sue proprietà, ne usare dei margine o stampare degli oggetti grafici, quindi all'occorrenza potremo rendere il processo di stampa un po' più elaborato usando i metodi descritti in seguito.

Impostare la stampante e le sue proprietà

Per  selezionare la stampante e di conseguenza le proprietà della pagina è possibile usare il componente TPageSetupDialog o il TPrintDialog (categoria componenti Dialogs). Questi sono dei componenti che includono una finestra di dialogo, tramite la quale è possibile selezionare la stampante da utilizzare e il formato della pagina.

Il primo componente, TPageSetupDialog, permette la personalizzazione della stampa tramite interfaccia utente (finestra di dialogo), mentre il secondo componente, TPrintDialog, permette di configurare i principali parametri da programma.

Un esempio di utilizzo potrebbe essere questo:

uses
  ...
  Printers,
  ...
procedure TForm1.ButtonStampaClick(Sender: TObject);
var
F: TextFile;
begin
  if PrinterSetupDialog1.Execute() then begin
    AssignPrn(F); { assegna il file di testo alla stampante }
    try
      Rewrite(F); { Occorre usare Rewrite dopo aver usato AssignPrn }
      WriteLn(F, 'Prova di stampa da Delphi.');
      WriteLn(F, 'Seconda riga.');
    finally
      CloseFile(F);
    end;
  end;
end;
 

Stampare oggetti grafici

Fino ad ora il processo di stampa è stato usato come un output testuale, ma se volessimo stampare un oggetto grafico, come un cerchio o una foto, dovremo usare l'oggetto TPrinter, all'interno della unit Printers. L'istanza di questo oggetto è legata a una variabile globale all'interno della suddetta unit e verrà creata al primo utilizzo della funzione printer.

Una volta creata questa variabile globale sarà possibile invocare i suoi metodi e sopratutto usarne la sua proprietà Canvas, che come per gli altri componenti grafici potrà essere usata per disegnarci dentro.

procedure TForm1.ButtonStampaClick(Sender: TObject);
begin
  Printer.BeginDoc;
  try
    //disegna una cornice intorno alla pagina
    Printer.Canvas.Rectangle(100, 100,Printer.PageWidth - 100, Printer.PageHeight - 100);
 
    //imposta la grandezza del font
    Printer.Canvas.Font.Size := 36;
    Printer.Canvas.Font.Style:=[fsBold];
    Printer.Canvas.Font.Name:='Tahoma';
 
    //inserisce un testo usando il font precedente
    Printer.Canvas.TextOut(150, 150, 'Stampa di prova');
  finally
    Printer.EndDoc;
  end;
end;
 

In questo semplice esempio si può notare come per poter disegnare sopra la Canvas è necessario richiamare il metodo BeginDoc, mentre per concludere la stampa occorre usare il metodo EndDoc.
Per disegnare una cornice intorno alla pagina sono stati usati alcuni parametri dell'oggetto TPrinter: PageWidth e PageHeight. Queste due proprietà identificano le dimensioni della pagina da usare. Nel caso specifico la stampante PDF è stata impostata a 300 punti per Inch e quindi per un formato A4(8.3"x11.7") questi valori saranno rispettivamente: 2480 per la larghezza(300*8.3) e 3508(300*11.7) per l'altezza.

Quindi ricapitolando, il contenitore grafico, che rappresenta il foglio della stampante, dove andremo a disegnare usa come unità i punti. Di questi dovremo tenere conto quando inseriremo coordinate e dimensioni degli oggetti grafici.

L'altezza e la larghezza del foglio possono essere inserite in millimetri o pollici (inch), ma vengono calcolati sempre in pollici. Quindi impostare il formato di una pagina significa fissare il numero di pollici in altezza e in larghezza per il foglio.

L'ultimo dato di cui tenere conto invece è la densità di punti per pollice (DPI = doth per inch), quindi per sapere la dimensione in punti della pagina dovremo moltiplicare le sue dimensioni espresse in pollici per la densità di punti per pollice.

Larghezza pagina (punti) = Densità (punti x pollice) * Larghezza pagina (pollici)

Purtroppo l'inserimento di un testo è equivalente ad un qualsiasi altro oggetto grafico e quindi dovremo essere noi a gestire l'andare a capo su più righe di un testo, valutando la larghezza del testo immesso e la larghezza massima di riga.

Per sapere a quanti punti in altezza e in larghezza corrisponde un determinato testo basta utilizzare le funzioni:

Printer.Canvas.TextWidth('testo');
Printer.Canvas.TextHeight('testo');

In questo modo sarà possibile rispettare i margini e la lunghezza di una pagina.

Come esempio finale riporto l'implementazione di una funzione che stampa il contenuto di un memo, rispettando i margini.

procedure TForm1.StampaMemo(memo:TMemo;PercentualeMargine:integer);
var
 MaxX,DimPaginaY,
 DimFoglioX,DimfoglioY,
 margine,MaxRighe,riga,
 AltezzaRiga,xPos,yPos,
 LarghezzaParola,i,k:integer;
 Lines:TStringList;
 Parola:string;
 oldwrap:boolean;
begin
  //crea una nuova lista di stringhe
  Lines:=TStringList.Create;
  //memorizza l'impostazione per andare a capo automaticamente del memo
  oldwrap:= memo.WordWrap;
  //elimina l'andare a capo automaticamente
  memo.WordWrap:=false;
  //copia le linee del memo nella nuova lista
  Lines.Assign(memo.Lines);
  //ripristina l'andare a capo automaticamente.
  memo.WordWrap:=oldwrap;
  //ricava l'altezza di una riga
  AltezzaRiga:=Printer.Canvas.TextHeight('M');
  //ricava le dimensioni di un foglio
  DimFoglioX:=Printer.PageWidth;
  DimFoglioY:=Printer.PageHeight;
  //calcola lo spessore del margine dal parametro PercentualeMargine
  margine:=round(DimFoglioX*PercentualeMargine/100);
  //calcola la posizione del margine a destra
  MaxX:=DimFoglioX-margine;
  //calcola l'altezza della pagina
  DimPaginaY:=DimfoglioY-2*margine;
  //calcola il numero massimo di righe
  MaxRighe:=round(DimPaginaY/AltezzaRiga);
  //assegna un titolo alla pagina
  Printer.Title:='Prova';
 
  //inizia la stampa
  Printer.BeginDoc;
  //imposta l'indice di riga ad 1
  riga:=1;
  //stampa ogni riga
  for i := 0 to Lines.Count - 1 do begin
    Lines[i]:=Lines[i]+' ';
    xPos:=margine;
    while Length(Lines[i])>0 do begin
      k:=Pos(' ',Lines[i]);
      if k>0 then begin
        //estrae la parola dalla riga attuale
        parola:=copy(Lines[i],1,k);
        //elimina la parola dalla riga
        Lines[i]:=copy(Lines[i],k+1,length(Lines[i]));
        //calcola la larghezza della parola da inserire
        LarghezzaParola:=Printer.Canvas.TextWidth(Parola);
        //se inserendo la parola si supera il margine
        //si passa alla riga successiva
        if xPos+LarghezzaParola>MaxX then begin
          inc(riga);   //nuova riga
          //se viene raggiunto il limite massimo di righe
          //crea una nuova pagina
          if riga>MaxRighe then begin
            Printer.NewPage;
            riga:=1;
          end;
          //riallinea la parola al margine sinistro
          xPos:=margine;
        end;
        //calcola la posizione vertivale di inserimento in base alla riga
        yPos:=round(AltezzaRiga*1.5)*riga+margine;
        //scrive o meglio disegna la parola
        Printer.Canvas.TextOut(xPos,yPos,Parola);
        //aggiorna la posizione orizzontale di inserimento
        xPos:=xPos+LarghezzaParola;
      end
      else  //se non ci sono più parole esce dal loop
        break;
    end;
    //passa alla riga successiva
    inc(riga);
    //se viene raggiunto il limite massimo di righe
    //crea una nuova pagina
    if riga>MaxRighe then begin
      Printer.NewPage;
      riga:=1;
    end;
  end;
  //termina la stampa
  Printer.EndDoc;
  Lines.Free;
end;

Un esempio di utilizzo potrebbe essere :

StampaMemo(Memo1,10);

dove si passa come parametro il nome dell'oggetto TMemo di cui si vuole stampare il contenuto e la dimensione del margine in percentuale rispetto la larghezza del foglio. Naturalmente sono state fatte delle semplificazioni, come ad esempio il mantenere la stessa dimensione dei margini orizzontali e verticali.

 

Ultimo aggiornamento ( Mercoledì 21 Marzo 2012 21:55 )  
Loading

Login




Chiudi