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

Bibliothèques tierces Python Discussion :

[reportlab] tableau intelligent en pdf ?


Sujet :

Bibliothèques tierces Python

  1. #1
    Membre habitué Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Points : 131
    Points
    131
    Par défaut [reportlab] tableau intelligent en pdf ?
    bonjour,

    Je voudrais generer un document pdf a partir de donnees.
    J'ai de suite pense a reportlab, car je l'ai deja utilise par le passe.

    Je suis un peu rouille avec reportlab, et je ne sais pas trop comment traiter mon probleme.
    J'aimerai avoir quelques conseils, pistes pour pouvoir avancer.

    Description du probleme:
    Objectif: generer automatiquement un pdf compact contenant les donnees d'entree.
    un genre de tableau qui s'adapte au contenu.
    Input:

    Ouput: un pdf (landscape) multicolonne
    Contraintes:
    • Odre des donnees:
      les donnees sont ordonnees dans l'input, elles devront l'etre dans l'output.
      un string d'input sera ecrit sur une ligne du pdf (multicolonne),
      Sur chaque page, l'ordre d'ecriture sera du haut vers le bas (dans une colonne), puis de gauche a droite pour l'ordre des colonnes.
      Puis, on continue de pages en pages jusqu'a epuisement des donnees.
    • Mise en page:
      la police, la taille de police et le contenu des strings piloteront le nombre de lignes et de colonnes de chaque page.
      En gros, la largeur de colonne est le max de la largeur du contenu de cette colonne.
      Et on ecrit le maximum de lignes par colonne.
      On peut mettre un separateur de colonne pour la visibilite.


    Ce n'est pas hyper complique et il doit bien y avoir des solutions pour ca.

    Pour le moment, jai 2 pistes:
    1. "a la main"
      en gros, je m'appuie sur les dimensions de la page et je place mes string a la main avec des coordonnees.
      Je crois qu'il existe une fonction qui me retourne les dimensions du rectangle contenant un string ecrit en fonction de la police et de sa taille.
      A partir de la, c'est juste un jeu de coordonnees.
      Le hic, c'est que pour le moment, je ne retrouve plus cette fonction et qu'il y a peut etre plus simple.
    2. avec les "table" de platypus
      en me rafraichissant sur reportlab, j'ai vu qu'il y avait des objets evolues qui pourraient avoir le comportement dont j'ai besoin.
      J'ai donc essaye de faire une table,
      mais je n'arrive pas trop a la manipuler pour obtenir le resultat voulu.


    Est-ce que vous auriez des pistes ? des suggestions ?

    merci.

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut Table platypus
    Salut,

    La doc de platypus est assez claire au sujet des tables.

    Lesquelles fonctionnent en colonne ensuite en ligne. Dans
    ton problème, tu expose l'inverse. La gestion des saut de page, avec rappel éventuel d'une ou plusieurs lignes d'en-tête se fait au niveau du nombre de ligne. De plus, si elles incorporent un algorithme pour calculer la largeur des colonnes, elle n'en n'ont aucun pour déterminer le nombre de colonnes d'après les largeurs de celle-ci.


    Tu peux néanmoins les utiliser mais, de toute manière, ce sera à ton programme de gérer lui même les dimensions de la page, le calcul de la largeur des colonnes et ensuite seulement leur nombre sur une page.

    Tu peux aussi diviser tes pages en colonnes de type journal avec les frames
    qui, elles, comportent déjà ce type de disposition. Je ne saurais trop t'expliquer comment vu que je ne les ai jamais utilisées. Toutefois, je suis quasi certain que tu devra quand même calculer les largeurs.

    Finalement, faire cela "à la main" n'est pas une si mauvaise idée car, si ton algorithme es très général, tu pourra assez facilement convertir ta fonction
    en un nouveau flowable utilisable par platypus partout où tu en aura besoin

    Programme intéressant donc, mais moins simple qu'il n'y paraît

    A bientôt

  3. #3
    Membre habitué Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Points : 131
    Points
    131
    Par défaut
    Bonjour,

    merci pour tes conseils.
    Finalement, je l'ai donc fait "a la main".

    J'ai trouve la fonction qui me donne la longueur d'un string:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from reportlab.pdfgen import canvas
    c = canvas.Canvas(...)
    c.stringWidth("monString")
    Par contre, je n'en ai pas trouve qui donne la hauteur, j'ai donc fait une approximation:
    Si quelqu'un a mieux, je suis preneur.

    Pour le trait vertical, je trace un rectangle plein.
    Il doit y avoir mieux, je suis egalement preneur.

    Voici donc un demonstrateur "a la vas-vite" qui fait a peu pres ce que je voulais:
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    # dumbTable.py
     
    from reportlab.pdfgen import canvas
    from reportlab.lib.pagesizes import landscape, A4
    from reportlab.lib.units import cm
     
    #################################################
    # data
    ## dList = ["Toto%s"%i for i in range(5000)]
    dList = ["Toto%s"%i if (i%1000 != 0) else "Oulalalalala%s"%i for i in range(5000)]
    print "dList:", len(dList), dList
    fontName = "Helvetica"
    fontSize = 8
    print "fontName, fontSize:", fontName, fontSize
    filename = "dumbTable.pdf"
    print "filename:", filename
    title = "dumbTable"
    widthMargin = 0.5
    heightMargin = 0.5
     
    #################################################
    # en attendant de trouver mieux
    def getHfromFont(fontName, fontSize):
      ""
     
      return (1.2*fontSize)
     
    #
    def getColFromList(dList, c, maxWidth, maxHeight, fontName, fontSize):
      "retourne la colonne a imprimmer et sa largeur. si la colonne est vide, c'est que ca ne rentre pas !!!"
     
      #
      colList = []
     
      #
      mw = 0
      currentH = 0
     
      while (len(dList) > 0):
        d = dList[0]
        w = c.stringWidth(d, fontName=fontName, fontSize=fontSize)
        h = getHfromFont(fontName, fontSize)
        if ((currentH + h < maxHeight) and (w < maxWidth)): # ok, add to col
          mw = max(mw, w)
          currentH += h
          colList.append(dList.pop(0))
        else: # KO, col is full(height) or will not fit(width)
          if (w >= maxWidth): # col will not fit in
            while (len(colList) > 0): # put them back in dList
              dList.insert(0, colList.pop())
          break
     
      #
      return colList, mw
     
    #################################################
    # page
    width, height = landscape(A4)
    print "width, height:", width, height
     
    #################################################
    # canvas
    myCanvas = canvas.Canvas(filename, pagesize=landscape(A4))
    myCanvas.setTitle(title)
    myCanvas.setFont(fontName, fontSize)
     
    #################################################
    # try 1
     
    xinit = widthMargin*cm
    yinit = height - heightMargin*cm - getHfromFont(fontName, fontSize)
    maxHeight = height - heightMargin*cm - heightMargin*cm
    x = xinit
    while (len(dList) > 0):
      myCanvas.setFont(fontName, fontSize)
      maxWidth = max(0, width - widthMargin*cm - x)
      print "maxWidth:", maxWidth
      y = yinit
      colList, mw = getColFromList(dList, myCanvas, maxWidth, maxHeight, fontName, fontSize)
      print "len(colList), mw:", len(colList), mw
      if (len(colList) > 0): # col fit on the same page
        # needs a new column on the same page
        print "-! needs a new COLUMN on the same page"
        for d in colList: # write column
          myCanvas.drawString(x, y, d)
          y -= getHfromFont(fontName, fontSize)
        if (x > xinit): # not first column => draw line
          myCanvas.rect(x - xinit/2, height - yinit - getHfromFont(fontName, fontSize), 0.25, maxHeight, fill=1)
        x += mw + xinit
      else: # col does not fit on the same page
        if (x == xinit): # KO, it will never fit :-(
          print "!!! error, it will never fit :-("
          break
        # needs a new page for the next column
        print "-! needs a new PAGE for the next column"
        myCanvas.showPage()
        x = xinit
     
    #
    myCanvas.save()
    Si vous avez des remarques, des ameliorations, n'hesitez pas.

    merci d'avance.

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

Discussions similaires

  1. SL3 export de pages, tableau, chart, en pdf et excel
    Par livinho38 dans le forum Silverlight
    Réponses: 5
    Dernier message: 28/07/2010, 15h55
  2. [2.3.2] Tableau et font pdf
    Par CCCMA dans le forum BIRT
    Réponses: 8
    Dernier message: 20/05/2009, 15h18
  3. [FPDF] Tableau Complexe en PDF
    Par mikadom dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 03/11/2008, 16h16
  4. Dessiner un tableau dans document PDF
    Par yosraisi dans le forum Autres composants
    Réponses: 8
    Dernier message: 04/03/2008, 17h59
  5. [FPDF] Tableau sur document PDF
    Par pollux75012 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 09/02/2007, 18h01

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