IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

TPrinter : Multipage sur sortie fichier ps [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2009
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2009
    Messages : 34
    Par défaut TPrinter : Multipage sur sortie fichier ps
    Bonjour à tous,
    Je découvre la classe TPrinter qui convient tout à fait mes besoins sauf que lors l'impression d'un document multipages, la version papier s'imprime comme il faut, alors que l'impression fichier n'imprime que la première page et laisse les pages suivantes vides.
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    procedure TMainForm.acPrintExecute(Sender: TObject);
    const
      LeftMargin   = 100;
      TopMargin    = 200;
      BottomMargin = 200;
      HEADLINE = 'APTEC sarl / Le ';
    var
      I, Y, LineHeight, NbPages: Integer;
      HeadMargin, FootMargin, TitleMargin : Integer;
      PrintString: String;
    begin
      // Fermer si la liste est vide
      if MainGrid.RowCount =1 then Exit;
      if PrintDialog.Execute then
      begin
        // Si Impression fichier alors init nom du fichier
        with Printer do
        try
          if PrintDialog.PrintToFile = true then
          begin
            FileName    := ExtractFileNameWithoutExt(OpenedFileName)+'.ps';
          end;
          Orientation := poReverseLandscape;                 // Orientation de la page
          //Orientation := poPortrait;
          LineHeight  := Round(1.2 * Abs(Canvas.TextHeight('I')));  // Calcule hauteur ligne
          // Démarre le document
          BeginDoc;
          Canvas.Font.Name  := 'Courier New'; // Init le nom de la police
          Canvas.Font.Color := clBlack;       // Init couleur de la police
          Canvas.Font.Size  := 10;            // Init taille de la police
          Canvas.Font.Bold  := true;
          // Calcule le nombre de pages
          NbPages     := ((LineHeight*MainGrid.RowCount)+(TopMargin*2))div PageHeight;
          // Imprimer entete document
          Y           := TopMargin;      // Position début écriture
          PrintString := HEADLINE + DateTimeToStr(Now)
                         +' - Page' +inttostr(PageNumber)
                         +'/'+inttostr(NbPages)+' - Document : '
                         +ExtractFileNameOnly(OpenedFileName);
          Canvas.TextOut(LeftMargin, Y, PrintString);
          Canvas.Line(LeftMargin, Y+LineHeight, PageWidth-LEFTMARGIN, Y+LineHeight);
          // Imprimer entete du tableau
          Canvas.Font.Size  := 12;         // Init taille de la police
          Y           := Y+(LineHeight);   // Position début écriture
          PrintString := Format('%-5s', ['Ordre'])+' '+
                         Format('%-10s', [MainGrid.Columns[6].Title.Caption])+' '+
                         Format('%-100s', [MainGrid.Columns[7].Title.Caption]);
          Canvas.TextOut(LeftMargin, Y, PrintString);
          //Imprimer listing
          Canvas.Font.Bold  := False;
          for i:=1 to MainGrid.RowCount-1 do
          begin
            if (Y >= (PageHeight-BottomMargin)) then
            begin
              Y := TopMargin;
              NewPage;
            end;
            Y           := Y+(LineHeight);
            PrintString := Format('%-5s', [MainGrid.Cells[0, i]])+' '+
                           Format('%-10s', [MainGrid.Cells[7, i]])+' '+
                           Format('%-100s', [MainGrid.Cells[8, i]]);
            Canvas.TextOut(LeftMargin, Y, PrintString);
            //ShowMessage(inttostr(Y));
     
          end;
        finally
          EndDoc;
        end;
      end;
    end;
    Je suis sous linux, j'ai solutionné temporairement par l'installation d'un driver pdf, mais je ne peux plus maîtriser ni le nom ni le repertoire du fichier sorti.
    Merci de votre aide.
    Salim.

  2. #2
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut
    Salut,

    Moi aussi je suis sous Linux (Debian Wheezy 7.1/32) et j'ai le même problème avec ton code.

    Faudrait que des utilisateurs sous Windows testent, ce qui est très simple : suffit de mettre un bouton, une StringGrid (et 9 colonnes dans le TGridColumns) et un PrintDialog sur une TForm, 2-3 adaptations et ça génère un fichier .ps, trop fastoche ! :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var
      MainForm: TMainForm;
      OpenedFileName: string;
     
    implementation
     
    procedure TMainForm.Button1Click(Sender: TObject);
    begin
      acPrintExecute(nil);
    end;
     
    procedure TMainForm.FormActivate(Sender: TObject);
    var
      r,c : integer;
    begin
      for r := 0 to MainGrid.RowCount-1 do
        for c := 0 to MainGrid.ColCount-1 do
          MainGrid.Cells[c,r] := IntToStr(r*c);
      OpenedFileName := 'à_adapter_testprintfile'
    end;
    sans oublier uses Printers;

    Un point qui m'a laissé perplexe (ou je m'y suis mal pris ?) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       with Printer do
       try
         if PrintDialog.PrintToFile = true then // False malgré le cochage de la case !
         // obligé de forcer l'option dans l'IDE et là, la case à cocher n'a plus d'action...
    Ah, pour l'esthétique, c'est mieux avec "+1" à la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         // Calcule le nombre de pages
         NbPages     := (((LineHeight*MainGrid.RowCount)+(TopMargin*2))div PageHeight)+1;

    Ce qui est très curieux dans cette affaire, c'est que si je rajoute Canvas.Line(LeftMargin, Y+LineHeight, PageWidth-LEFTMARGIN, Y+LineHeight); avant la ligne chargée d'imprimer le texte, tout en bas, j'ai bien autant de lignes noires affichées que j'ai de Rows dans la StringGrid (j'en ai déclaré 70), mais le texte n'est présent que sur la première page, comme indiqué par l'OP
    On dirait que Canvas.TextOut perd les pédales après Printer.NewPage

    Ça donne quoi sous Windows ? (parce que le code a l'air sain, j'ai passé pas mal de temps à farfouiller le web, tous les tutos se rejoignent...)

    Citation Envoyé par larsal007 Voir le message
    (...) j'ai solutionné temporairement par l'installation d'un driver pdf, mais je ne peux plus maîtriser ni le nom ni le répertoire du fichier sorti.
    Salim.
    Ça, ça devrait pouvoir se gérer par un petit script Bash après génération du fichier, éventuellement, non ?

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2009
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2009
    Messages : 34
    Par défaut
    Bonjour,
    Merci pour ton aide.

    Citation Envoyé par Jipété Voir le message
    Moi aussi je suis sous Linux (Debian Wheezy 7.1/32) et j'ai le même problème avec ton code.
    ......
    Un point qui m'a laissé perplexe (ou je m'y suis mal pris ?) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       with Printer do
       try
         if PrintDialog.PrintToFile = true then // False malgré le cochage de la case !
         // obligé de forcer l'option dans l'IDE et là, la case à cocher n'a plus d'action...
    Ah, pour l'esthétique, c'est mieux avec "+1" à la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         // Calcule le nombre de pages
         NbPages     := (((LineHeight*MainGrid.RowCount)+(TopMargin*2))div PageHeight)+1;
    ......
    Ça donne quoi sous Windows ? (parce que le code a l'air sain, j'ai passé pas mal de temps à farfouiller le web, tous les tutos se rejoignent...)

    Ça, ça devrait pouvoir se gérer par un petit script Bash après génération du fichier, éventuellement, non ?
    Je suis également sous debian wheezy 7.4 sur deux machines qui donnent le même résultat. Je testerais lundi sur windows et Ubuntu pour voir.

    Concernant le composant TPrintDialog, il faut mettre les deux propriétés PrintToFile et Options.poPrintToFile à True en mode DesignTime. Dans ce cas là, ça marchera lorsque tu cocheras l'option "Print To File" de la boite de dialogue une fois l'application lancée.

    Merci pour le calcul du nombre de pages, je ne l'avais pas vu.

    J'ai installé le paquet cups-pdf qui imprime le pdf dans le repertoire "home/user/PDF", il suffit de renommer le fichier le plus récent et de l'afficher avec Evince ou un form+composant sous Lazarus. (Je n'ai pas encore décidé mais j'opte pour la deuxième solution).

    Je n'ai jamais posté un rapport de bug. Penses tu qu'il faut le faire ou est ce prématuré?

    Salim.

  4. #4
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut
    Yep !
    Citation Envoyé par larsal007 Voir le message
    (...) Concernant le composant TPrintDialog, il faut mettre les deux propriétés PrintToFile et Options.poPrintToFile à True en mode DesignTime. Dans ce cas là, ça marchera lorsque tu cocheras l'option "Print To File" de la boite de dialogue une fois l'application lancée. (...)
    Me suis rendu compte qu'en mettant ces 2 options, il n'y a même pas besoin de cocher la case de la boîte de dialogue d'impression, ça génère le fichier quand même !

    Citation Envoyé par larsal007 Voir le message
    (...) Je n'ai jamais posté un rapport de bug. Penses-tu qu'il faut le faire ou est-ce prématuré ?
    Moi non plus
    Perso, j'attendrais un peu, genre les tests sous Windows avec exactement le même code source, et en fonction des résultats...

    Mais c'est possible qu'on s'oriente vers un bug, oui... : cet aprème j'ai encore un peu joué avec ça, justement, j'ai épuré au maximum (plus de StringGrid, plus d'impression des en-têtes), et le problème est toujours là. Vraiment bizarre...

    Préparons le rapport de bug, fais simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
         ...
         //Orientation := poReverseLandscape;                 // Orientation de la page
         Orientation := poPortrait; // idem
         LineHeight  := Round(1.2 * Abs(Canvas.TextHeight('I')));  // Calcule hauteur ligne
         // Démarre le document
         BeginDoc;
    //     Canvas.Font.Name  := 'Courier New'; // Init le nom de la police
         Canvas.Font.Name  := 'DejaVu Sans Mono'; // Init le nom de la police
         Canvas.Font.Color := clBlack;       // Init couleur de la police
         Canvas.Font.Size  := 10;            // Init taille de la police
         Canvas.Font.Bold  := False;
     
         Y := TopMargin;      // Position début écriture = 200
         for i := 1 to 70 do // 70 pour avoir 2 pages (la 1re va de 1 à 52)
         begin
           if (Y >= (PageHeight-BottomMargin)) then
           begin
             NewPage;
             Y := TopMargin; // Position début écriture = 200
           end;
           Y           := Y+(LineHeight);
           PrintString := 'Ligne de test + '+ IntToStr(i);
           Canvas.TextOut(LeftMargin, Y, PrintString);
         end;
         ...
    Bon week-end,

  5. #5
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Par défaut
    Bonjour,
    Citation Envoyé par Jipété Voir le message
    Ça donne quoi sous Windows ? (parce que le code a l'air sain, j'ai passé pas mal de temps à farfouiller le web, tous les tutos se rejoignent...)
    Eh bien, comment dire ? euhh ?
    En reprenant le code fourni par @larsal007 et en rajoutant les 3 bricoles dont a parlé @Jipété, cela ne se passe pas comme prévu. Cela ne passe pas du tout en fait !
    J'obtiens une exception sur la ligne 26 de la procédure acPrintExecute
    Le projet a levé une classe d'exception EInvalidOperation avec le message :
    Canvas does not allow drawing
    Le test a été réalisé avec Lazarus 1.2.0, sous Windows XP 32 bits et sous Windows 2000 32 bits qui ont au moins un pilote d'imprimante installé...

    L'application n'aurait donc pas de handle valide pour le canvas en question.

  6. #6
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut
    Bonsoir,

    et merci d'avoir tenté.
    Citation Envoyé par Ph. B. Voir le message
    (...) J'obtiens une exception sur la ligne 26 de la procédure acPrintExecute (...)
    Sur cette ligne ? (qui vient du post d'origine) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         LineHeight  := Round(1.2 * Abs(Canvas.TextHeight('I')));  // Calcule hauteur ligne

  7. #7
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Par défaut
    Bonjour,
    Citation Envoyé par Jipété Voir le message
    Sur cette ligne ? (qui vient du post d'origine) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         LineHeight  := Round(1.2 * Abs(Canvas.TextHeight('I')));  // Calcule hauteur ligne
    C'est elle même...

    Citation Envoyé par Jipété Voir le message
    Si tu as 5 minutes, jette un œil ici, ça n'a pas trop de rapport mais les commentaires sont intéressants.
    J'avais fait aussi cette recherche... Ce qui me laisserait penser que sous Windows, il y aurait un loupé ?

    Sachant que sous Linux 32 bits (XUbuntu 12.04.4), ca ne plante pas, mais je reproduis le défaut initialement constaté (2° page blanche).

  8. #8
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut
    Bonsoir,
    Citation Envoyé par Ph. B. Voir le message
    C'est elle même...
    As-tu essayé de forcer, genre ...Abs(Printer.Canvas.TextHeight('I'))); ?

    Ou de voir ce que propose la complétion sur Printer.Canvas. ?

    Citation Envoyé par Ph. B. Voir le message
    (...) je reproduis le défaut initialement constaté (2° page blanche).
    T'as vu ça ? C'est un truc de fou

  9. #9
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 127
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 127
    Par défaut Le problème n'est pas là où on le pensait !
    Ce matin, je ne sais pas pourquoi, il m'est venu une intuition subite, en regardant le titre utilisé pour poster dans le forum Lazarus :
    TPrinter : Multipage problem with output PS File
    output PS File...
    Me suis souvenu que les fichiers TIFF géraient le multipage, ni une ni deux, je remplace l'extension dans le code, je lance, ça me génère donc un .TIFF, ouverture avec GIMP et là, bingo !
    J'ai bien deux pages remplies de lignes !

    Le souci (car il y a toujours un souci ), c'est que le .TIFF généré n'est pas un vrai fichier image (même si GIMP sait l'importer) : impossible à transformer en PDF, impossible de lire ses infos :
    # tiffinfo testprintfile.tiff
    testprintfile.tiff: Not a TIFF or MDI file, bad magic number 8485 (0x2125).
    Normal : le début du fichier (vu avec un éditeur hexa) = %!PS-Adobe-3.0.%, et plus loin : %%Creator: Lazarus PostCriptCanvas.

    Je recopie le .TIFF en .PS, je double-clique et je retrouve le problème d'origine ! Seconde page vide, alors que ses infos sont bien dans le fichier (très visibles avec l'éditeur hexa)

    Pas simple cette histoire...

    [ EDIT ] La solution est ensuite toute bête, puisque le fichier .PS a un contenu correct : l'outil PS2PDF fait parfaitement son boulot, comme son nom l'indique, et le PDF généré affiche correctement les 2 pages.

    Et c'est peut-être juste l'outil d'affichage des .PS qui a un souci, sous Linux comme sous Windows...
    [ /EDIT ]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/04/2012, 21h30
  2. Réponses: 0
    Dernier message: 07/04/2011, 15h05
  3. Sortie des informations sur un fichier
    Par ayoubnour dans le forum Langage
    Réponses: 5
    Dernier message: 15/06/2009, 09h00
  4. sortie sur 3 fichiers
    Par yamnetouaga dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 29/03/2007, 07h36
  5. [Oracle] Requête sur 3 tables, sortie fichier
    Par Bast92 dans le forum Langage SQL
    Réponses: 20
    Dernier message: 18/04/2006, 15h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo