def test0(self):
        "This makes one long multi-page paragraph."

        # Build story.
        story = []
        styleSheet = getSampleStyleSheet()
        bt = styleSheet['BodyText']
        text = '''If you imagine that the box of X's tothe left is
an image, what I want to be able to do is flow a
series of paragraphs around the image
so that once the bottom of the image is reached, then text will flow back to the
left margin. I know that it would be possible to something like this
using tables, but I can't see how to have a generic solution.
There are two examples of this in the demonstration section of the reportlab
site.
If you look at the "minimal" euro python conference brochure, at the end of the
timetable section (page 8), there are adverts for "AdSu" and "O'Reilly". I can
see how the AdSu one might be done generically, but the O'Reilly, unsure...
I guess I'm hoping that I've missed something, and that
it's actually easy to do using platypus.
'''
        from reportlab.platypus.flowables import ParagraphAndImage, Image
        from reportlab.lib.testutils import testsFolder
        gif = os.path.join(testsFolder,'pythonpowered.gif')
        story.append(ParagraphAndImage(Paragraph(text,bt),Image(gif)))
        phrase = 'This should be a paragraph spanning at least three pages. '
        description = ''.join([('%d: '%i)+phrase for i in xrange(250)])
        story.append(ParagraphAndImage(Paragraph(description, bt),Image(gif),side='left'))

        doc = MyDocTemplate(outputfile('test_platypus_paragraphandimage.pdf'))
        doc.multiBuild(story)
 def wrap(self, availWidth, availHeight):
     # print "# wrap", id(self), self.canv
     # availHeight = self.setMaxHeight(availHeight)
     self.I.canv = self.canv
     result = ParagraphAndImage.wrap(self, availWidth, availHeight)
     del self.I.canv
     return result
 def wrap(self, availWidth, availHeight):
     # print "# wrap", id(self), self.canv
     # availHeight = self.setMaxHeight(availHeight)
     self.I.canv = self.canv
     result = ParagraphAndImage.wrap(self, availWidth, availHeight)
     del self.I.canv
     return result
def myFirstPage(canvas, doc):
    canvas.saveState()
    canvas.setFont('Times-Bold', 16)
    canvas.drawCentredString(PAGE_WIDTH / 2.0, PAGE_HEIGHT - 108, title)
    canvas.setFont('Times-Roman', 9)
    canvas.drawString(inch, 0.75 * inch, "Page %d - %s" % (doc.page, title))

    frame_width = PAGE_WIDTH - 200
    hr = HRFlowable()
    space = Spacer(frame_width, 20)
    style = styles["Normal"]
    qr_info = """<para rightIndent=10 leftIndent=20 alignment=right>This document is signed with the QR code shown on the right. Validate it using a Barcode Scanner."""
    par = Paragraph(qr_info, style)
    im = Image("qrcode.png", 101, 101)
    pandi = ParagraphAndImage(par, im, xpad=3, ypad=30, side='right')

    frame = Frame(100, 0, frame_width, 200, showBoundary=1)
    frame.add(hr, canvas)
    frame.add(space, canvas)
    frame.add(pandi, canvas)
    canvas.restoreState()
    def Imprimer(self, event=None):
        listeDates = self.dictImpression["dates"]
        if len(listeDates) > 26 :
            dlg = wx.MessageDialog(self, _(u"Désolé mais vous ne pouvez pas imprimer plus de 26 jours sur une feuille !"), _(u"Information"), wx.OK | wx.ICON_EXCLAMATION)
            dlg.ShowModal()
            dlg.Destroy()
            return False
        
        # Création du PDF
        from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
        from reportlab.platypus.flowables import ParagraphAndImage, Image
        from reportlab.rl_config import defaultPageSize
        from reportlab.lib.units import inch, cm
        from reportlab.lib.utils import ImageReader
        from reportlab.lib import colors
        from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
        self.hauteur_page = defaultPageSize[1]
        self.largeur_page = defaultPageSize[0]
        
        # Recherche le format de la page à appliquer
        largeurPremiereColonne = 140
        largeurColonnesDates = 24
        largeurMax = largeurPremiereColonne + (largeurColonnesDates*len(listeDates))
        
        if largeurMax <= 520 :
            # Format Portrait
            largeurPage, hauteurPage = defaultPageSize
            largeurContenu = 520
        else :
            # Format Paysage
            hauteurPage, largeurPage = defaultPageSize
            largeurContenu = 770

        # Initialisation du PDF
        nomDoc = FonctionsPerso.GenerationNomDoc("LISTE_TRANSPORTS", "pdf")
        if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\")
        doc = SimpleDocTemplate(nomDoc, pagesize=(largeurPage, hauteurPage), topMargin=30, bottomMargin=30)
        story = []
        
        # Création du titre du document
        def Header():
            dataTableau = []
            largeursColonnes = ( (largeurContenu-100, 100) )
            dateDuJour = DateEngFr(str(datetime.date.today()))
            dataTableau.append( (_(u"Liste des transports"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour)) )
            style = TableStyle([
                    ('BOX', (0,0), (-1,-1), 0.25, colors.black), 
                    ('VALIGN', (0,0), (-1,-1), 'TOP'), 
                    ('ALIGN', (0,0), (0,0), 'LEFT'), 
                    ('FONT',(0,0),(0,0), "Helvetica-Bold", 16), 
                    ('ALIGN', (1,0), (1,0), 'RIGHT'), 
                    ('FONT',(1,0),(1,0), "Helvetica", 6), 
                    ])
            tableau = Table(dataTableau, largeursColonnes)
            tableau.setStyle(style)
            story.append(tableau)
            story.append(Spacer(0,20))       
        
        # Insère un header
        Header() 
        
        # Contenu
        for dictCategorie in self.dictImpression["donnees"] :
            label = dictCategorie["texte"]
            img = dictCategorie["img"]
            elements = dictCategorie["elements"]
            
            dataTableau = []
            largeursColonnes = [largeurPremiereColonne,]
            
            # Création de la ligne de date
            paraStyle = ParagraphStyle(name="categorie",
                      fontName="Helvetica-Bold",
                      fontSize=9,
                      leading=8,
                      spaceAfter=2,)

            ligne = [ParagraphAndImage(Paragraph(label, paraStyle), Image(Chemins.GetStaticPath("Images/32x32/%s.png" % img), width=8, height=8), xpad=1, ypad=0, side="left"),]
            for date in listeDates :
                ligne.append(u"%02d/%02d\n%04d" % (date.day, date.month, date.year))
                largeursColonnes.append(largeurColonnesDates)
            dataTableau.append(ligne)
        
            # Création des lignes
            listeExtraStyles = []
            index = 1
            for element in elements :
                
                # Décoration de la ligne
                if element["type"] in ("lieux", "lignes", "localisations") :
                    listeExtraStyles.append(('BACKGROUND', (0, index), (-1, index), (0.8, 0.8, 1) ))

                if element["type"] == "arrets" :
                    listeExtraStyles.append(('BACKGROUND', (0, index), (-1, index), (0.9, 0.9, 1) ))

                if element["type"] == "heures" :
                    listeExtraStyles.append(('FONT',(0, index), (0, index), "Helvetica-Bold", 6),)
                    listeExtraStyles.append(('FONT',(1, index), (-1, index), "Helvetica", 5),)
                    listeExtraStyles.append(('TEXTCOLOR',(1, index), (-1, index), (0.6, 0.6, 0.6)),)

                if element["type"] == "individus" :
                    listeExtraStyles.append(('ALIGN', (0, index), (0, index), 'RIGHT'))
                    listeExtraStyles.append(('GRID', (1, index), (-1, index), 0.25, colors.black))
                    listeExtraStyles.append(('FONT',(1, index), (-1, index), "Helvetica", 6),)

                # Ajout d'une marge
                label = element["texte"]
                if "marge" in element :
                    label = u"%s%s" % ((element["marge"]-1) * "      ", label)
                ligne = [label,]
                
                # Ajout des colonnes
                for indexColonne in range(1, len(largeursColonnes)) :
                    label = u""
                    if "colonnes" in element:
                        if indexColonne in element["colonnes"] :
                            label = element["colonnes"][indexColonne]
                    ligne.append(label)
                
                dataTableau.append(ligne)
                index += 1
        
            # Style du tableau
            listeStyles = [
                    ('VALIGN', (0, 0), (-1,-1), 'MIDDLE'), 
                    ('ALIGN', (1, 0), (-1, -1), 'CENTRE'),
                    ('FONT',(0, 0), (-1,-1), "Helvetica", 7), 
                    ('FONT',(0, 0), (0, 0), "Helvetica-Bold", 8),
                    ('BOX', (0, 1), (-1, -1), 0.25, colors.black), 
                    ('GRID', (1, 0), (-1, 0), 0.25, colors.black), 
                    ]
            
            for extraStyle in listeExtraStyles :
                listeStyles.append(extraStyle)
                
            # Création du tableau
            tableau = Table(dataTableau, largeursColonnes)
            tableau.setStyle(TableStyle(listeStyles))
            story.append(tableau)
            story.append(Spacer(0, 15))
        
##        # TOTAUX
##        dataTableau = []
##        largeursColonnes = [220, 220, 40, 40]
##
##        for ligne in self.listeImpression["totaux"] :
##            dataTableau.append(ligne) 
##
##        couleurFond = (0.8, 0.8, 0.8)
##        listeStyles = [
##                ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases
##                ('FONT',(0,0),(-1,-1), "Helvetica", 7), # Donne la police de caract. + taille de police 
##                ('BOX', (0, 1), (-1,-1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau
##                ('ALIGN', (2, 0), (-1, -1), 'CENTRE'), # Ligne de labels colonne alignée au centre
##                ('BOX', (0, 0), (-1,0), 0.25, colors.black), # Crée la bordure noire du nom de famille
##                ('FONT',(0,0),(0,0), "Helvetica-Bold", 8), # Donne la police de caract. + taille de police du titre de groupe
##                ('BACKGROUND', (0,0), (-1,0), couleurFond), # Donne la couleur de fond du titre de groupe
##                ('TOPPADDING',(0,0),(-1,-1), 1), 
##                ('BOTTOMPADDING',(0,0),(-1,-1), 1), 
##                ]
##            
##        # Création du tableau
##        tableau = Table(dataTableau, largeursColonnes)
##        tableau.setStyle(TableStyle(listeStyles))
##        story.append(tableau)

        # Enregistrement du PDF
        doc.build(story)
        
        # Affichage du PDF
        FonctionsPerso.LanceFichierExterne(nomDoc)
 def split(self, availWidth, availHeight):
     # print "# split", id(self)
     if not hasattr(self, "wI"):
         self.wI, self.hI = self.I.wrap(availWidth, availHeight)  # drawWidth, self.I.drawHeight
     return ParagraphAndImage.split(self, availWidth, availHeight)
 def split(self, availWidth, availHeight):
     # print "# split", id(self)
     if not hasattr(self, "wI"):
         self.wI, self.hI = self.I.wrap(availWidth, availHeight)  # drawWidth, self.I.drawHeight
     return ParagraphAndImage.split(self, availWidth, availHeight)
 def wrap(self, availWidth, availHeight):
     self.I.canv = self.canv
     result = ParagraphAndImage.wrap(self, availWidth, availHeight)
     del self.I.canv
     return result
 def wrap(self, availWidth, availHeight):
     self.I.canv = self.canv
     result = ParagraphAndImage.wrap(self, availWidth, availHeight)
     del self.I.canv
     return result
Beispiel #10
0
    def OnBoutonOk(self, event):
        # Récupération et vérification des données
        listePeriodes = self.ctrl_calendrier.GetDatesSelections()

        listeActivites = self.ctrl_activites.GetListeActivites()
        if len(listeActivites) == 0:
            dlg = wx.MessageDialog(
                self,
                _(u"Vous devez obligatoirement cocher au moins une activité !"
                  ), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION)
            dlg.ShowModal()
            dlg.Destroy()
            return False

        listeGroupes = self.ctrl_groupes.GetListeGroupes()
        if len(listeGroupes) == 0:
            dlg = wx.MessageDialog(
                self,
                _(u"Vous devez obligatoirement cocher au moins un groupe !"),
                _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION)
            dlg.ShowModal()
            dlg.Destroy()
            return False

        # Création du PDF
        from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
        from reportlab.platypus.flowables import ParagraphAndImage, Image
        from reportlab.rl_config import defaultPageSize
        from reportlab.lib.pagesizes import A4
        from reportlab.lib.units import inch, cm
        from reportlab.lib.utils import ImageReader
        from reportlab.lib import colors
        from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle

        self.taille_page = A4
        self.orientation = "PAYSAGE"
        if self.orientation == "PORTRAIT":
            self.hauteur_page = self.taille_page[1]
            self.largeur_page = self.taille_page[0]
        else:
            self.hauteur_page = self.taille_page[0]
            self.largeur_page = self.taille_page[1]

        # Création des conditions pour les requêtes SQL
        conditionsPeriodes = GetSQLdates(listePeriodes)

        if len(listeActivites) == 0: conditionActivites = "()"
        elif len(listeActivites) == 1:
            conditionActivites = "(%d)" % listeActivites[0]
        else:
            conditionActivites = str(tuple(listeActivites))

        if len(listeGroupes) == 0: conditionGroupes = "()"
        elif len(listeGroupes) == 1:
            conditionGroupes = "(%d)" % listeGroupes[0]
        else:
            conditionGroupes = str(tuple(listeGroupes))

        # Récupération des noms des groupes
        dictGroupes = self.ctrl_groupes.GetDictGroupes()

        # Récupération des noms d'activités
        dictActivites = self.ctrl_activites.GetDictActivites()

        # Récupération de la liste des groupes ouverts sur cette période
        DB = GestionDB.DB()
        req = """SELECT IDouverture, IDactivite, IDunite, IDgroupe
        FROM ouvertures 
        WHERE ouvertures.IDactivite IN %s AND %s
        AND IDgroupe IN %s
        ; """ % (conditionActivites, conditionsPeriodes, conditionGroupes)
        DB.ExecuterReq(req)
        listeOuvertures = DB.ResultatReq()
        dictOuvertures = {}
        for IDouverture, IDactivite, IDunite, IDgroupe in listeOuvertures:
            if dictOuvertures.has_key(IDactivite) == False:
                dictOuvertures[IDactivite] = []
            if IDgroupe not in dictOuvertures[IDactivite]:
                dictOuvertures[IDactivite].append(IDgroupe)

        # Récupération des individus grâce à leurs consommations
        DB = GestionDB.DB()
        req = """SELECT individus.IDindividu, IDactivite, IDgroupe, etat,
        IDcivilite, nom, prenom, date_naiss
        FROM consommations 
        LEFT JOIN individus ON individus.IDindividu = consommations.IDindividu
        WHERE etat IN ("reservation", "present")
        AND IDactivite IN %s AND %s
        GROUP BY individus.IDindividu
        ORDER BY nom, prenom
        ;""" % (conditionActivites, conditionsPeriodes)
        DB.ExecuterReq(req)
        listeIndividus = DB.ResultatReq()
        dictIndividus = {}
        listeIDindividus = []

        for IDindividu, IDactivite, IDgroupe, etat, IDcivilite, nom, prenom, date_naiss in listeIndividus:
            if date_naiss != None: date_naiss = DateEngEnDateDD(date_naiss)
            age = self.GetAge(date_naiss)

            # Mémorisation de l'individu
            dictIndividus[IDindividu] = {
                "IDcivilite": IDcivilite,
                "nom": nom,
                "prenom": prenom,
                "age": age,
                "date_naiss": date_naiss,
                "IDgroupe": IDgroupe,
                "IDactivite": IDactivite,
            }

            # Mémorisation du IDindividu
            if IDindividu not in listeIDindividus:
                listeIDindividus.append(IDindividu)

        # Dict Informations médicales
        req = """SELECT IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical,
        description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction
        FROM problemes_sante 
        WHERE diffusion_listing_enfants=1
        ;"""
        DB.ExecuterReq(req)
        listeInformations = DB.ResultatReq()
        DB.Close()
        dictInfosMedicales = {}
        for IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction in listeInformations:
            if dictInfosMedicales.has_key(IDindividu) == False:
                dictInfosMedicales[IDindividu] = []
            dictTemp = {
                "IDprobleme": IDprobleme,
                "IDtype": IDtype,
                "intitule": intitule,
                "date_debut": date_debut,
                "date_fin": date_fin,
                "description": description,
                "traitement_medical": traitement_medical,
                "description_traitement": description_traitement,
                "date_debut_traitement": date_debut_traitement,
                "date_fin_traitement": date_fin_traitement,
                "eviction": eviction,
                "date_debut_eviction": date_debut_eviction,
                "date_fin_eviction": date_fin_eviction,
            }
            dictInfosMedicales[IDindividu].append(dictTemp)

        # Récupération des photos individuelles
        dictPhotos = {}
        taillePhoto = 128
        if self.ctrl_taille_photos.GetSelection() == 0: tailleImageFinal = 16
        if self.ctrl_taille_photos.GetSelection() == 1: tailleImageFinal = 32
        if self.ctrl_taille_photos.GetSelection() == 2: tailleImageFinal = 64
        if self.checkbox_photos.GetValue() == True:
            for IDindividu in listeIDindividus:
                IDcivilite = dictIndividus[IDindividu]["IDcivilite"]
                nomFichier = Chemins.GetStaticPath(
                    "Images/128x128/%s" %
                    DICT_CIVILITES[IDcivilite]["nomImage"])
                IDphoto, bmp = CTRL_Photo.GetPhoto(IDindividu=IDindividu,
                                                   nomFichier=nomFichier,
                                                   taillePhoto=(taillePhoto,
                                                                taillePhoto),
                                                   qualite=100)

                # Création de la photo dans le répertoire Temp
                nomFichier = UTILS_Fichiers.GetRepTemp(
                    fichier="photoTmp%d.jpg" % IDindividu)
                bmp.SaveFile(nomFichier, type=wx.BITMAP_TYPE_JPEG)
                img = Image(nomFichier,
                            width=tailleImageFinal,
                            height=tailleImageFinal)
                dictPhotos[IDindividu] = img

        # ---------------- Création du PDF -------------------

        # Initialisation du PDF
        nomDoc = FonctionsPerso.GenerationNomDoc(
            "LISTE_INFORMATIONS_MEDICALES", "pdf")
        if sys.platform.startswith("win"): nomDoc = nomDoc.replace("/", "\\")
        doc = SimpleDocTemplate(nomDoc,
                                pagesize=(self.largeur_page,
                                          self.hauteur_page),
                                topMargin=30,
                                bottomMargin=30)
        story = []

        largeurContenu = self.largeur_page - 75  #520

        # Création du titre du document
        def Header():
            dataTableau = []
            largeursColonnes = ((largeurContenu - 100, 100))
            dateDuJour = DateEngFr(str(datetime.date.today()))
            dataTableau.append(
                (_(u"Informations médicales"), _(u"%s\nEdité le %s") %
                 (UTILS_Organisateur.GetNom(), dateDuJour)))
            style = TableStyle([
                ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                ('ALIGN', (0, 0), (0, 0), 'LEFT'),
                ('FONT', (0, 0), (0, 0), "Helvetica-Bold", 16),
                ('ALIGN', (1, 0), (1, 0), 'RIGHT'),
                ('FONT', (1, 0), (1, 0), "Helvetica", 6),
            ])
            tableau = Table(dataTableau, largeursColonnes)
            tableau.setStyle(style)
            story.append(tableau)
            story.append(Spacer(0, 20))

        # Insère un header
        Header()

        # Activités
        for IDactivite in listeActivites:
            nomActivite = dictActivites[IDactivite]["nom"]
            # Groupes
            if dictOuvertures.has_key(IDactivite):
                nbreGroupes = len(dictOuvertures[IDactivite])
                indexGroupe = 1
                for IDgroupe in dictOuvertures[IDactivite]:
                    nomGroupe = dictGroupes[IDgroupe]["nom"]

                    # Initialisation du tableau
                    dataTableau = []
                    largeursColonnes = []
                    labelsColonnes = []

                    # Recherche des entêtes de colonnes :
                    if self.checkbox_photos.GetValue() == True:
                        labelsColonnes.append(_(u"Photo"))
                        largeursColonnes.append(tailleImageFinal + 6)

                    labelsColonnes.append(_(u"Nom - prénom"))
                    largeursColonnes.append(120)

                    if self.checkbox_age.GetValue() == True:
                        labelsColonnes.append(_(u"Âge"))
                        largeursColonnes.append(20)

                    # Calcule la largeur restante
                    largeurRestante = largeurContenu - sum(largeursColonnes)

                    labelsColonnes.append(_(u"Informations alimentaires"))
                    largeursColonnes.append(largeurRestante / 2.0)

                    labelsColonnes.append(_(u"Informations diverses"))
                    largeursColonnes.append(largeurRestante / 2.0)

                    # Création de l'entete de groupe
                    ligne = [
                        nomGroupe,
                    ]
                    for x in range(0, len(labelsColonnes) - 1):
                        ligne.append("")
                    dataTableau.append(ligne)

                    # Création des entêtes
                    ligne = []
                    for label in labelsColonnes:
                        ligne.append(label)
                    dataTableau.append(ligne)

                    # --------- Création des lignes -----------

                    # Création d'une liste temporaire pour le tri
                    listeIndividus = []
                    if dictOuvertures.has_key(IDactivite):
                        if IDgroupe in dictOuvertures[IDactivite]:
                            for IDindividu in listeIDindividus:
                                dictIndividu = dictIndividus[IDindividu]
                                if dictIndividu["IDgroupe"] == IDgroupe:
                                    valeursTri = (IDindividu,
                                                  dictIndividu["nom"],
                                                  dictIndividu["prenom"],
                                                  dictIndividu["age"])

                                    # + Sélection uniquement des individus avec infos
                                    if self.checkbox_nonvides.GetValue(
                                    ) == False or (
                                            self.checkbox_nonvides.GetValue()
                                            == True and dictInfosMedicales.
                                            has_key(IDindividu)):
                                        listeIndividus.append(valeursTri)

                    if self.ctrl_tri.GetSelection() == 0: paramTri = 1  # Nom
                    if self.ctrl_tri.GetSelection() == 1:
                        paramTri = 2  # Prénom
                    if self.ctrl_tri.GetSelection() == 2: paramTri = 3  # Age
                    if self.ctrl_ordre.GetSelection() == 0:
                        ordreDecroissant = False
                    else:
                        ordreDecroissant = True
                    listeIndividus = sorted(listeIndividus,
                                            key=operator.itemgetter(paramTri),
                                            reverse=ordreDecroissant)

                    # Récupération des lignes individus
                    for IDindividu, nom, prenom, age in listeIndividus:
                        dictIndividu = dictIndividus[IDindividu]

                        ligne = []

                        # Photo
                        if self.checkbox_photos.GetValue(
                        ) == True and IDindividu in dictPhotos:
                            img = dictPhotos[IDindividu]
                            ligne.append(img)

                        # Nom
                        ligne.append(u"%s %s" % (nom, prenom))

                        # Age
                        if self.checkbox_age.GetValue() == True:
                            if age != None:
                                ligne.append(age)
                            else:
                                ligne.append("")

                        # Informations médicales
                        paraStyle = ParagraphStyle(
                            name="infos",
                            fontName="Helvetica",
                            fontSize=7,
                            leading=8,
                            spaceAfter=2,
                        )

                        listeInfosAlim = []
                        listeInfosDivers = []
                        if dictInfosMedicales.has_key(IDindividu):
                            for infoMedicale in dictInfosMedicales[IDindividu]:
                                intitule = infoMedicale["intitule"]
                                description = infoMedicale["description"]
                                traitement = infoMedicale["traitement_medical"]
                                description_traitement = infoMedicale[
                                    "description_traitement"]
                                date_debut_traitement = infoMedicale[
                                    "date_debut_traitement"]
                                date_fin_traitement = infoMedicale[
                                    "date_fin_traitement"]
                                IDtype = infoMedicale["IDtype"]
                                # Intitulé et description
                                if description != None and description != "":
                                    texteInfos = u"<b>%s</b> : %s" % (
                                        intitule, description)
                                else:
                                    texteInfos = u"%s" % intitule
                                if len(texteInfos
                                       ) > 0 and texteInfos[-1] != ".":
                                    texteInfos += u"."
                                # Traitement médical
                                if traitement == 1 and description_traitement != None and description_traitement != "":
                                    texteDatesTraitement = u""
                                    if date_debut_traitement != None and date_fin_traitement != None:
                                        texteDatesTraitement = _(
                                            u" du %s au %s"
                                        ) % (DateEngFr(date_debut_traitement),
                                             DateEngFr(date_fin_traitement))
                                    if date_debut_traitement != None and date_fin_traitement == None:
                                        texteDatesTraitement = _(
                                            u" à partir du %s") % DateEngFr(
                                                date_debut_traitement)
                                    if date_debut_traitement == None and date_fin_traitement != None:
                                        texteDatesTraitement = _(
                                            u" jusqu'au %s") % DateEngFr(
                                                date_fin_traitement)
                                    texteInfos += _(u"Traitement%s : %s.") % (
                                        texteDatesTraitement,
                                        description_traitement)

                                # Création du paragraphe
                                img = DICT_TYPES_INFOS[IDtype]["img"]
                                p = ParagraphAndImage(
                                    Paragraph(texteInfos, paraStyle),
                                    Image(Chemins.GetStaticPath(
                                        "Images/16x16/%s" % img),
                                          width=8,
                                          height=8),
                                    xpad=1,
                                    ypad=0,
                                    side="left")
                                if infoMedicale["IDtype"] == 2:
                                    listeInfosAlim.append(p)
                                else:
                                    listeInfosDivers.append(p)

                            ligne.append(listeInfosAlim)
                            ligne.append(listeInfosDivers)

                        # Ajout de la ligne individuelle dans le tableau
                        dataTableau.append(ligne)

                    # Création des lignes vierges
                    if self.checkbox_lignes_vierges.GetValue() == True:
                        for x in range(
                                0,
                                self.ctrl_nbre_lignes.GetSelection() + 1):
                            ligne = []
                            for col in labelsColonnes:
                                ligne.append("")
                            dataTableau.append(ligne)

                    # Style du tableau
                    colPremiere = 1
                    if self.checkbox_photos.GetValue() == True:
                        colPremiere += 1
                    if self.checkbox_age.GetValue() == True:
                        colPremiere += 1

                    couleurFond = (0.8, 0.8, 1)  # Vert -> (0.5, 1, 0.2)

                    style = TableStyle([
                        ('VALIGN', (0, 0), (-1, -1),
                         'MIDDLE'),  # Centre verticalement toutes les cases
                        ('FONT', (0, 0), (-1, -1), "Helvetica",
                         7),  # Donne la police de caract. + taille de police 
                        ('GRID', (0, 0), (-1, -1), 0.25, colors.black
                         ),  # Crée la bordure noire pour tout le tableau
                        ('ALIGN', (0, 1), (-2, -1),
                         'CENTRE'),  # Centre les cases
                        ('ALIGN', (0, 1), (-1, 1), 'CENTRE'
                         ),  # Ligne de labels colonne alignée au centre
                        (
                            'FONT', (0, 1), (-1, 1), "Helvetica", 6
                        ),  # Donne la police de caract. + taille de police des labels
                        (
                            'SPAN', (0, 0), (-1, 0)
                        ),  # Fusionne les lignes du haut pour faire le titre du groupe
                        (
                            'FONT', (0, 0), (0, 0), "Helvetica-Bold", 10
                        ),  # Donne la police de caract. + taille de police du titre de groupe
                        ('BACKGROUND', (0, 0), (-1, 0), couleurFond
                         ),  # Donne la couleur de fond du titre de groupe
                    ])

                    # Création du tableau
                    tableau = Table(dataTableau, largeursColonnes)
                    tableau.setStyle(style)
                    story.append(tableau)
                    story.append(Spacer(0, 20))

                    # Saut de page après un groupe
                    if self.checkbox_page_groupe.GetValue() == True:
                        story.append(PageBreak())
                        # Insère un header
                        if indexGroupe < nbreGroupes:
                            Header()

                    indexGroupe += 1

        # Enregistrement du PDF
        doc.build(story)

        # Affichage du PDF
        FonctionsPerso.LanceFichierExterne(nomDoc)

        self.MemoriserParametres()