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)
Ejemplo n.º 2
0
 def fill_sender(self):
     """Fills sender identity"""
     from reportlab.platypus.flowables import Image
     from core.pdf.utils import Paragraph
     # Sender identity
     sender_paragraphs = []
     if self.invoice_base.current_revision.sender:
         sender_paragraphs.append(
             Paragraph(self.invoice_base.current_revision.sender,
                       self.style['Small']))
     sender_paragraphs.append(
         Paragraph(self.invoice_base.tenant.name, self.style['Small']))
     if self.invoice_base.current_revision.sender_address:
         sender_paragraphs.append(
             Paragraph(
                 u'\n'.join(self.invoice_base.current_revision.
                            sender_address.get_formatted()),
                 self.style['Small']))
     # Add layout table if logo or paragraphs
     if self.invoice_base.tenant.logo_cache:
         logo = Image(self.invoice_base.tenant.logo_cache)
         logo_width, logo_height = logo._restrictSize(50 * mm, 20 * mm)
         self.table([[logo, sender_paragraphs]],
                    (logo_width + 4 * mm, None),
                    self.style['LayoutTable'],
                    rowHeights=(20 * mm, ))
     else:
         for paragraph in sender_paragraphs:
             self.append(paragraph)
Ejemplo n.º 3
0
 def reportHeader(self):
     
     reportLogo = Image(self.app.engine.logo)
     reportLogo.drawHeight = 0.80 * inch 
     reportLogo.drawWidth =  1.20 * inch
     
     t = Table((('Data Report','',[reportLogo]),
                ("Start Date",self.start_date.strftime('%d/%m/%Y'),''),
                ("Category",self.category,''),
                ("Supplier",self.supplier,''),
                ("Records",len(self.rs),'')),
               #colWidths, rowHeights,
               (80,80,250),
               (18,18,18,18,18,))
     #('SPAN',(2,0),(2,-1)) expand image
     t.setStyle(TableStyle([#column, row
                            ('SPAN',(2,0),(2,-1)),
                            ('BOX',(0,1),(1,-1),0.5,colors.lightgrey),
                            ('LINEABOVE',(0,-1),(1,-1),0.5,colors.lightgrey),
                            ('TEXTCOLOR', (1,1),(1,-3),colors.red, 10),
                            ('TEXTCOLOR', (1,1),(1,-4),colors.blue, 10),
                            #('GRID',(0,1),(1,-1), 0.2, colors.black),
                            ('ALIGN',(1,0),(-1,-1),'CENTER'),
                            ('FONT', (0,0),(0,0),'Times-Bold', 18),]))
     return t
Ejemplo n.º 4
0
    def draw_header(self):
        if self.preview:
            t = self.canvas.beginText()
            t.setTextOrigin(cm(6), cm(4))
            t.setFont("DejaVu Serif Italic", 70)
            t.setFillColorRGB(0.9, 0.9, 0.9)
            t.textLine("PREVIEW PREVIEW")
            self.canvas.rotate(45)
            self.canvas.drawText(t)
            self.canvas.rotate(-45)

        if self.logo:
            im = Image(self.logo, width=cm(3), height=cm(3))
            im.drawOn(self.canvas, cm(2), cm(25))

        if self.headertext:
            t = self.canvas.beginText()
            t.setFillColor(colors.black)
            t.setFont("DejaVu Serif", 9)
            t.setTextOrigin(cm(6), cm(27.5))
            self.textlines(t, self.headertext)
            self.canvas.drawText(t)

        if self.sendertext:
            self._draw_multiline_aligned(self.sendertext,
                                         cm(2), cm(23.5), cm(9), cm(4))

        self._draw_multiline_aligned("To:\n%s" % self.recipient,
                                     cm(11), cm(23.5), cm(9), cm(4))

        p = self.canvas.beginPath()
        p.moveTo(cm(2), cm(18.9))
        p.lineTo(cm(19), cm(18.9))
        self.canvas.drawPath(p)
Ejemplo n.º 5
0
class Figure(Flowable):

    def __init__(self, imgFile, captionTxt, captionStyle, imgWidth=None, imgHeight=None, margin=(0, 0, 0, 0),
                 padding=(0, 0, 0, 0), align=None, borderColor=(0.75, 0.75, 0.75), no_mask=False, url=None):

        imgFile = imgFile
        self.imgPath = imgFile
        # workaround for http://code.pediapress.com/wiki/ticket/324
        # see http://two.pairlist.net/pipermail/reportlab-users/2008-October/007526.html
        if no_mask:
            self.i = Image(imgFile, width=imgWidth, height=imgHeight, mask=None)
        else:
            self.i = Image(imgFile, width=imgWidth, height=imgHeight)
        self.imgWidth = imgWidth
        self.imgHeight = imgHeight
        self.c = Paragraph(captionTxt, style=captionStyle)
        self.margin = margin  # 4-tuple. margins in order: top, right, bottom, left
        self.padding = padding  # same as above
        self.borderColor = borderColor
        self.align = align
        self.cs = captionStyle
        self.captionTxt = captionTxt
        self.availWidth = None
        self.availHeight = None
        self.url = url

    def draw(self):
        canv = self.canv
        if self.align == "center":
            canv.translate((self.availWidth - self.width) / 2, 0)
        canv.saveState()
        canv.setStrokeColor(Color(self.borderColor[0], self.borderColor[1], self.borderColor[2]))
        canv.rect(self.margin[3], self.margin[2], self.boxWidth, self.boxHeight)
        canv.restoreState()
        canv.translate(self.margin[3] + self.padding[3], self.margin[2] + self.padding[2] - 2)
        self.c.canv = canv
        self.c.draw()
        canv.translate((self.boxWidth - self.padding[1] - self.padding[3] - self.i.drawWidth) / 2, self.captionHeight + 2)
        self.i.canv = canv
        self.i.draw()
        if self.url:
            frags = urlparse.urlsplit(self.url.encode('utf-8'))
            clean_url = urlparse.urlunsplit((frags.scheme,
                                             frags.netloc,
                                             urllib.quote(frags.path, safe='/'),
                                             urllib.quote(frags.query, safe='=&'),
                                             frags.fragment,)).decode('utf-8')
            canv.linkURL(clean_url, (0, 0, self.imgWidth, self.imgHeight), relative=1, thickness=0)

    def wrap(self, availWidth, availHeight):
        self.availWidth = availWidth
        self.availHeight = availHeight
        contentWidth = max(self.i.drawWidth, self.c.wrap(self.i.drawWidth, availHeight)[0])
        self.boxWidth = contentWidth + self.padding[1] + self.padding[3]
        (self.captionWidth, self.captionHeight) = self.c.wrap(contentWidth, availHeight)
        self.captionHeight += self.cs.spaceBefore + self.cs.spaceAfter
        self.boxHeight = self.i.drawHeight + self.captionHeight + self.padding[0] + self.padding[2]
        self.width = self.boxWidth + self.margin[1] + self.margin[3]
        self.height = self.boxHeight + self.margin[0] + self.margin[2]
        return (self.width, self.height)
Ejemplo n.º 6
0
def myFirstPage(canvas, doc):
    canvas.saveState()
    canvas.setFont('Helvetica-Bold', 20)
    canvas.drawCentredString(PAGE_WIDTH / 2.0, PAGE_HEIGHT - 108, Title)
    canvas.drawCentredString(PAGE_WIDTH / 2.0, PAGE_HEIGHT - 130, Date)
    im = Image("lucicoin.png", width=2 * inch, height=2 * inch)
    im.hAlign = 'LEFT'
    canvas.setFont('Helvetica', 9)
    canvas.drawString(inch, 0.75 * inch, "First Page / %s" % pageinfo)
    canvas.restoreState()
Ejemplo n.º 7
0
 def draw(self):
     canvas = self.canv
     img = Image(self.barcode)
     width, height = img.wrapOn(canvas, 0, 0)
     width = width * 72. / 300
     height = height * 72. / 300
     canvas.drawImage(
         self.barcode,
         self.x * mm,
         (self.y * mm * -1) - height,
         width,
         height,
     )
Ejemplo n.º 8
0
 def draw(self):
     canvas = self.canv
     img = Image(self.barcode)
     width, height = img.wrapOn(canvas, 0, 0)
     width = width * 72. / 300
     height = height * 72. / 300
     canvas.drawImage(
         self.barcode,
         self.x * mm,
         (self.y * mm * -1) - height,
         width,
         height,
     )
Ejemplo n.º 9
0
 def insert_image(self,
                  path: str,
                  x: int = 100,
                  y: int = 200,
                  width: int = None,
                  height: int = None):
     """
     This function inserts image in pdf-file\n
     size of page is 595.27,841.89\n
     :param path: path to image
     :param x, y: coordinates of left-bottom corner of image
     :param width, height: sizes of image
     """
     image = Image(path, width, height)
     image.drawOn(self.file, x, y)
Ejemplo n.º 10
0
	def _pageheader(self):
		if self.preview:
			t = self.canvas.beginText()
			t.setTextOrigin(6*cm, 4*cm)
			t.setFont("Times-Italic", 70)
			t.setFillColorRGB(0.9,0.9,0.9)
			t.textLines("PREVIEW PREVIEW")
			self.canvas.rotate(45)
			self.canvas.drawText(t)
			self.canvas.rotate(-45)

		im = Image("%s/PostgreSQL_logo.1color_blue.300x300.png" % self.imagedir, width=3*cm, height=3*cm)
		im.drawOn(self.canvas, 2*cm, 25*cm)
		t = self.canvas.beginText()
		t.setFillColorRGB(0,0,0,0)
		t.setFont("Times-Roman", 10)
		t.setTextOrigin(6*cm, 27.5*cm)
		t.textLines("""PostgreSQL Europe
Carpeaux Diem
13, rue du Square Carpeaux
75018 PARIS
France
""")
		self.canvas.drawText(t)

		t = self.canvas.beginText()
		t.setTextOrigin(2*cm, 23*cm)
		t.setFont("Times-Roman", 10)
		t.textLine("")
		t.textLines("""
Your contact: Guillaume Lelarge
Function: PostgreSQL Europe Treasurer
E-mail: [email protected]
""")
		self.canvas.drawText(t)

		t = self.canvas.beginText()
		t.setTextOrigin(11*cm, 23*cm)
		t.setFont("Times-Italic", 11)
		t.textLine("To:")
		t.setFont("Times-Roman", 11)
		t.textLines(self.recipient)
		self.canvas.drawText(t)

		p = self.canvas.beginPath()
		p.moveTo(2*cm, 18.9*cm)
		p.lineTo(19*cm, 18.9*cm)
		self.canvas.drawPath(p)
Ejemplo n.º 11
0
    def myFirstPage(self, canvas, doc):
        Image('PhEDEx-banner.png', width=A4[0],
              height=100).drawOn(canvas, 0, (A4[1] - 100))
        self.allPages(canvas, doc)

        style = self.getStyle()
        date = self.getDate()
        P = Paragraph("%s PhEDEx Report" % self.site, style["ReportTitle"])
        size = P.wrap(A4[0], 200)
        #Because we're drawing 'raw' paragraphs need to wrap them
        P.wrapOn(canvas, A4[0], size[1])
        top = 10 + size[1]
        P.drawOn(canvas, 0, A4[1] - top)

        P = Paragraph("Week beginning %s" % date, style["ReportTitleDate"])
        size = P.wrap(A4[0], 200)
        P.wrapOn(canvas, A4[0], size[1])
        top = top + size[1]
        P.drawOn(canvas, 0, A4[1] - top)

        P = Paragraph("%s Instance" % self.instance, style["ReportSubTitle"])
        size = P.wrap(A4[0], 200)
        P.wrapOn(canvas, A4[0], size[1])
        top = top + size[1]
        P.drawOn(canvas, 0, A4[1] - top)
Ejemplo n.º 12
0
    def doSubscriptions(self):
        style = self.getStyle()
        text = """There have been 21 subscription requests this week. 
        All have been approved| X were approved, Y rejected, 
        Z are still to be considered. """

        png = 'Picture 1.png'

        subscriptionsPara = [
            Spacer(inch * .25, inch * .25),
            Paragraph('Subscriptions', style['SectionTitle']),
            Paragraph(text, style=style["Normal_just_rind"]),
            Spacer(inch * .125, inch * .125),
            Paragraph(self.doRequests(), style=style["Normal_just_rind"]),
            Spacer(inch * .25, inch * .25)
        ]
        subscriptionsImg = ImageAndFlowables(Image(png, width=180, height=180),
                                             subscriptionsPara,
                                             imageLeftPadding=0,
                                             imageRightPadding=0,
                                             imageSide='right')

        return KeepTogether(
            [subscriptionsImg,
             Spacer(inch * .125, inch * .125)])
Ejemplo n.º 13
0
def defaultimage(filename, width=None, height=None, kind='direct',
                                        mask="auto", lazy=1, srcinfo=None):
    ''' We have multiple image backends, including the stock reportlab one.
        This wrapper around the reportlab one allows us to pass the client
        RstToPdf object and the uri into all our backends, which they can
        use or not as necessary.
    '''
    return Image(filename, width, height, kind, mask, lazy)
Ejemplo n.º 14
0
 def __init__(self,
              filename,
              width,
              height,
              margin=0,
              kind='direct',
              mask="auto",
              lazy=1):
     Image.__init__(self,
                    filename,
                    width=None,
                    height=None,
                    kind=kind,
                    mask=mask,
                    lazy=lazy)
     self.r_width = width
     self.r_height = height
     self._restrictSize(self.r_width - margin * 2, self.r_height)
Ejemplo n.º 15
0
 def _draw_image(self, img_path, width=None, height=None, **kwargs):
     """Draw an image"""
     canvas = self.canv
     img = Image(img_path)
     _width, _height = img.wrapOn(canvas, 0, 0)
     _width = _width * 72. / 300
     _height = _height * 72. / 300
     if width is not None:
         _width = width
     if height is not None:
         _height = height
     canvas.drawImage(
         img_path,
         self.cursor.x * self.unit,
         self.cursor.y * self.unit - _height,
         _width,
         _height,
     )
Ejemplo n.º 16
0
def create_user_info_document(output_file, teacher_list):
    logger.debug('Creating user info document...')
    subject_paragraph_style = ParagraphStyle(name='Normal',
                                             fontSize=12,
                                             leading=20,
                                             fontName='Times-Bold',
                                             spaceAfter=0.75 * cm)
    main_paragraph_style = ParagraphStyle(name='Normal',
                                          fontSize=11,
                                          leading=18,
                                          fontName='Times-Roman',
                                          spaceAfter=0.25 * cm,
                                          hyphenationLang='de_DE',
                                          embeddedHyphenation=1,
                                          uriWasteReduce=0.3)
    data_paragraph_style = ParagraphStyle(name='Normal',
                                          fontSize=11,
                                          fontName='Courier',
                                          spaceAfter=0.5 * cm,
                                          alignment=TA_CENTER)
    # prepare data for document
    title = 'Benutzerdaten'
    author = 'bbst - BBS Teacher Management'
    logo = Image('logo.png',
                 width=PAGE_WIDTH - 2 * BORDER_HORIZONTAL,
                 height=5.2445 * cm,
                 hAlign='CENTER')
    info_text_greeting = 'Liebe Kollegin, lieber Kollege,<br/>ihre Benutzerdaten lauten wie folgt:'
    info_text_paragraphs = [
        """Diese Zugangsdaten erlauben die Rechnernutzung in allen Räumen mit dem Logodidact-System.
    Außerdem kann es zum Zugriff auf den Stundenplan über WebUntis und die Lernplattform Moodle genutzt werden.""",
        """In Logodidact, Moodle und WebUntis lässt sich das Passwort ändern. Allerdings gilt jede Änderung nur für
    das jeweilige System! Sollten Sie ihr Passwort vergessen haben, besteht bei Moodle und Webuntis die
    Möglichkeit, sich ein neues Passwort per Mail zusenden zu lassen.""",
        """Weitere Informationen finden Sie im Moodle-Kurs unter
    <a color="blue" href="https://moodle.nibis.de/bbs_osb/course/view.php?id=7">https://moodle.nibis.de/bbs_osb/course/view.php?id=7</a>.
    Bei allen weiteren Fragen können Sie sich gerne bei mir melden.""",
        """<br/>Viele Grüße<br/>&nbsp;&nbsp;&nbsp;&nbsp;Christian Wichmann<br/>&nbsp;&nbsp;&nbsp;&nbsp;[email protected]"""
    ]
    # building document
    doc = SimpleDocTemplate(output_file, author=author, title=title)
    story = []
    for t in teacher_list:
        user_data = '{}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}'.format(
            t.username.lower(), t.password)
        story.append(logo)
        story.append(Spacer(1, 1.75 * cm))
        story.append(
            Paragraph('<b>{}</b>'.format(title), subject_paragraph_style))
        story.append(Paragraph(info_text_greeting, main_paragraph_style))
        story.append(Paragraph(user_data, data_paragraph_style))
        for p in info_text_paragraphs:
            story.append(Paragraph(p, main_paragraph_style))
        story.append(PageBreak())
    doc.build(story, onFirstPage=build_footer, onLaterPages=build_footer)
Ejemplo n.º 17
0
    def myLaterPages(self, canvas, doc):
        Image('PhEDEx-banner.png', width=A4[0],
              height=75).drawOn(canvas, 0, (A4[1] - 75))
        self.allPages(canvas, doc)

        style = self.getStyle()
        date = self.getDate()
        P = Paragraph("%s PhEDEx Report" % self.site, style["ReportTitle"])
        size = P.wrap(A4[0], 200)
        P.wrapOn(canvas, A4[0], size[1])
        top = 10 + size[1]
        P.drawOn(canvas, 0, A4[1] - top)
Ejemplo n.º 18
0
 def wrap(self, availWidth, availHeight):
     #print 123, self.drawWidth, self.drawHeight, self.pisaZoom
     #self.drawWidth *= self.pisaZoom
     #self.drawHeight *= self.pisaZoom
     # print 456, self.drawWidth, self.drawHeight
     width = min(self.drawWidth, availWidth)
     # print 999, width, self.drawWidth, availWidth
     factor = float(width) / self.drawWidth
     # print 123, factor
     self.drawHeight = self.drawHeight * factor
     self.drawWidth = width
     return Image.wrap(self, availWidth, availHeight)
Ejemplo n.º 19
0
 def wrap(self, availWidth, availHeight):
     #print 123, self.drawWidth, self.drawHeight, self.pisaZoom
     #self.drawWidth *= self.pisaZoom
     #self.drawHeight *= self.pisaZoom
     # print 456, self.drawWidth, self.drawHeight
     width = min(self.drawWidth, availWidth)
     # print 999, width, self.drawWidth, availWidth
     factor = float(width) / self.drawWidth
     # print 123, factor
     self.drawHeight = self.drawHeight * factor
     self.drawWidth = width
     return Image.wrap(self, availWidth, availHeight)
Ejemplo n.º 20
0
 def __init__(self,imgFile, captionTxt, captionStyle, imgWidth=None, imgHeight=None, margin=(0,0,0,0), padding=(0,0,0,0), align=None, borderColor=(0.75,0.75,0.75), no_mask=False, url=None):
     imgFile = imgFile 
     self.imgPath = imgFile
     # workaround for http://code.pediapress.com/wiki/ticket/324
     # see http://two.pairlist.net/pipermail/reportlab-users/2008-October/007526.html
     if no_mask:
         self.i = Image(imgFile, width=imgWidth, height=imgHeight, mask=None)
     else:
         self.i = Image(imgFile, width=imgWidth, height=imgHeight)
     self.imgWidth = imgWidth
     self.imgHeight = imgHeight
     self.c = Paragraph(captionTxt, style=captionStyle)
     self.margin = margin # 4-tuple. margins in order: top, right, bottom, left
     self.padding = padding # same as above
     self.borderColor = borderColor
     self.align = align
     self.cs = captionStyle
     self.captionTxt = captionTxt
     self.availWidth = None
     self.availHeight = None
     self.url = url
Ejemplo n.º 21
0
	def __init__( self, attrs ):
		
		# PIL is required to draw images
		try:
			import PIL
		except ImportError:
			Error("""
PIL (Python Imaging Library) is required to use images in 
your documents. 
You should download and install it. 
http://www.pythonware.com/products/pil/
				""")
		
		Properties.__init__(self)
		self.graphic( attrs )
		
		if self.properties['src']:
			self.filename = self.properties['src']
		else:
			Error('No source defined for external-graphic element.')
		
		Image.__init__( self, self.filename )
Ejemplo n.º 22
0
    def add_image(self, src, width, height, align=CENTER, caption=None):

        if src.split(".")[-1] in ["png", "PNG"]:
            try:
                f = open(src, 'rb')
                data = StringIO(f.read())
            except:
                return
            else:
                img = Image(data, width, height)
                f.close()
        else:
            img = Image(src, width, height)

        img.hAlign = align
        if caption:
            caption_p = Paragraph(caption, self.theme.paragraph_centered)
            image_table = Table([[img], [caption_p]], width)
            image_table.setStyle(
                TableStyle([('ALIGN', (-1, -1), (-1, -1), 'CENTER')]))
            self.add(image_table)
        else:
            self.add(img)
Ejemplo n.º 23
0
    def add_image(self, src, width, height, align=CENTER, caption=None):

        if src.split(".")[-1] in ["png", "PNG"]:
            try:
                f = open(src, 'rb')
                data = StringIO(f.read())
            except:
                return
            else:
                img = Image(data, width, height)
                f.close()
        else:
            img = Image(src, width, height)
        
        img.hAlign = align
        if caption:
            caption_p = Paragraph(caption, self.theme.paragraph_centered)
            image_table = Table([[img], [caption_p]], width)
            image_table.setStyle(TableStyle([('ALIGN',(-1,-1),(-1,-1),
                'CENTER')]))
            self.add(image_table)
        else:       
            self.add(img)
Ejemplo n.º 24
0
    def allPages(self, canvas, doc):
        #Background images
        Image('phedex_outline.png', width=A4[0] - 50,
              height=A4[0] - 50).drawOn(canvas, 25, (A4[1] / 2) - (A4[0] / 2))

        #Footer text
        style = self.getStyle()
        date = self.getDate()
        P = Paragraph(
            "%s PhEDEx Report for week beginning %s  - Page %d" %
            (self.site, date, doc.page), style["Footer"])
        size = P.wrap(A4[0], 200)
        P.wrapOn(canvas, A4[0] - 20, size[1])
        top = 10 + size[1]
        P.drawOn(canvas, 0, top)
Ejemplo n.º 25
0
 def fill_sender(self):
     """Fills sender identity"""
     from reportlab.platypus.flowables import Image
     from core.pdf.utils import Paragraph
     # Sender identity
     sender_paragraphs = []
     if self.invoice_base.current_revision.sender:
         sender_paragraphs.append(Paragraph(self.invoice_base.current_revision.sender, self.style['Small']))
     sender_paragraphs.append(Paragraph(self.invoice_base.tenant.name, self.style['Small']))
     if self.invoice_base.current_revision.sender_address:
         sender_paragraphs.append(Paragraph(u'\n'.join(self.invoice_base.current_revision.sender_address.get_formatted()), self.style['Small']))
     # Add layout table if logo or paragraphs
     if self.invoice_base.tenant.logo_cache:
         logo = Image(self.invoice_base.tenant.logo_cache)
         logo_width, logo_height = logo._restrictSize(50*mm, 20*mm)
         self.table(
             [[logo, sender_paragraphs]],
             (logo_width + 4*mm, None),
             self.style['LayoutTable'],
             rowHeights=(20*mm,)
         )
     else:
         for paragraph in sender_paragraphs:
             self.append(paragraph)
Ejemplo n.º 26
0
def defaultimage(
    filename,
    width=None,
    height=None,
    kind='direct',
    mask='auto',
    lazy=1,
    srcinfo=None,
):
    """Get default image backend.

    We have multiple image backends, including the stock ReportLab one.  This
    wrapper around the ReportLab one allows us to pass the client ``RstToPdf``
    object and the URI into all our backends, which they can use (or not) as
    necessary.
    """
    return Image(filename, width, height, kind, mask, lazy)
Ejemplo n.º 27
0
 def doImport(self):
     style = self.getStyle()
     text = '''Import transfer rates and quality for %s. 
     Maximum daily rate is 237MB/s, minimum rate is 100MB/s, 
     average 169/MB/s. Average quality for the week is 30 percent.''' % self.site
     importPara = [
         Spacer(inch * .25, inch * .25),
         Paragraph('Data Import', style['SectionTitle']),
         Paragraph(text, style=style["Normal_just"])
     ]
     png = 'Picture 1.png'
     importImg = ImageAndFlowables(Image(png, width=340, height=240),
                                   importPara,
                                   imageLeftPadding=0,
                                   imageRightPadding=20,
                                   imageSide='left')
     return KeepTogether([importImg, Spacer(inch * .125, inch * .125)])
Ejemplo n.º 28
0
 def resize_images(self, story):
     # replace images with resized ones fitting into the available width
     W, H = (self.width - self.lm -
             self.rm), self.height - self.tm - self.bm
     for i, el in enumerate(story):
         if el.__class__ == Image:
             img = PIL.Image.open(el.filename)
             h = W / img.size[0] * img.size[1]
             img = Image(el.filename,
                         width=w,
                         height=h,
                         kind='direct',
                         mask="auto",
                         lazy=1)
             story[i] = img
         elif type(el) == str:
             story[i] = Paragraph(el, bt)  # Spacer(0, 0)
Ejemplo n.º 29
0
    def __init__(self, title, enterprise, interval, logo):
        self.title = title
        self.enterprise = enterprise
        self.interval = interval
        self.logo = logo
        self.width, self.height = A4
        self.buf = StringIO()
        self.canvas = Canvas(self.buf, pagesize=A4)

        self.page_title = ''
        self.page_rows = []
        self.page_frags = 0
        self.page_num = 1

        # Build story.
        self.canvas.saveState()
        self.canvas.setStrokeColor(colors.RED)
        self.canvas.setLineWidth(2)
        self.canvas.roundRect(self.margin, self.edenwall_height + self.margin, self.width, self.height, 20, stroke=1, fill=0)

        self.canvas.setFillColor(colors.GREEN2)
        self.canvas.setStrokeColor(colors.GREEN1)
        self.canvas.roundRect(- self.margin, - self.margin, self.width - self.margin, self.edenwall_height + self.margin,
                              20, stroke=1, fill=1)
        # TODO do not hardcode this values.
        img = Image('/var/lib/ufwi_rpcd/edenwall.png', 1209 / (300/(self.edenwall_height-self.margin/2)), self.edenwall_height-self.margin/2)
        img.drawOn(self.canvas, self.margin, self.margin/4)

        self.canvas.restoreState()

        if self.logo:
            img = Image(StringIO(self.logo))
            img._setup_inner()
            img.drawOn(self.canvas, (self.width - self.margin)/2 - img.drawWidth/2, 2*self.height/3)

        offset = 40

        self.canvas.setFillColor(black)
        self.canvas.setFont("Helvetica-Bold", self.big_title_height)
        self.canvas.drawCentredString((self.width-self.margin)/2, self.height/3, title)
        self.canvas.setFont("Helvetica-Bold", self.frag_title_height)
        self.canvas.drawString(offset, self.height - offset, enterprise)
Ejemplo n.º 30
0
 def AddTableRow(self, element):
     cells = []
     color = self._ConvertColor(element, "background")
     if color is not None:
         start = (0, len(self.tableRows))
         stop = (-1, len(self.tableRows))
         self.tableCommands.append(("BACKGROUND", start, stop, color))
     for cell in element:
         if cell.tag == "td":
             rowSpan = int(cell.get("rowspan", 1))
             colSpan = int(cell.get("colspan", 1))
             if rowSpan > 1 or colSpan > 1:
                 start = (len(cells), len(self.tableRows))
                 stop = (len(cells) + colSpan - 1,
                         len(self.tableRows) + rowSpan - 1)
                 self.tableCommands.append(("SPAN", start, stop))
             color = self._ConvertColor(cell, "background")
             if color is not None:
                 start = stop = (len(cells), len(self.tableRows))
                 self.tableCommands.append(
                     ("BACKGROUND", start, stop, color))
             contents = []
             for child in cell:
                 if child.tag == "para":
                     styleName = child.get("style", "default")
                     rotated = self._ConvertNumber(child, "rotate")
                     style = self.paragraphStyles[styleName]
                     child.attrib.clear()
                     text = cElementTree.tostring(child)
                     cls = RotatedParagraph if rotated else Paragraph
                     para = cls(text, style)
                     contents.append(para)
                 elif child.tag == "img":
                     fileName = child.get("src", "unknown.png")
                     width = self._ConvertNumber(child, "width")
                     height = self._ConvertNumber(child, "height")
                     img = Image(fileName, width, height)
                     contents.append(img)
             if not contents:
                 contents = cell.text and cell.text.strip()
             cells.append(contents)
     height = self._ConvertNumber(element, "height")
     self.tableRows.append(cells)
     self.tableRowHeights.append(height)
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()
Ejemplo n.º 32
0
def __plot_common_(width, method, p=0.48):
    fig = plt.figure(figsize=(15, 15*p))
    plt.grid(axis="y", linestyle="-", color="#637a8f", linewidth=2)

    method()

    # plt.xticks(fontsize=12)
    # plt.yticks(fontsize=12)

    ax = plt.gca()
    ax.set_axisbelow(True)
    ax.spines['top'].set_color("none")
    ax.spines['right'].set_color("none")
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')

    img_data = io.BytesIO()
    fig.savefig(img_data, format='png')
    img_data.seek(0)
    im = Image(img_data, width=width, height=width * p)
    return [im, Spacer(6, 20)]
Ejemplo n.º 33
0
def get_doc_elements(queryset, med_p=False):
    elements = []
    summary_data = []
    already_added_images = []
    for qs in queryset.order_by("invoice_number"):
        dd = [
            qs.prestations.all().order_by("date", "carecode__name")[i:i + 20]
            for i in range(0, len(qs.prestations.all()), 20)
        ]
        for _prestations in dd:
            _inv = qs.invoice_number + (
                ("" + str(dd.index(_prestations) + 1) +
                 qs.invoice_date.strftime('%m%Y')) if len(dd) > 1 else "")
            _result = _build_invoices(_prestations, _inv, qs.invoice_date,
                                      qs.accident_id, qs.accident_date)

            elements.extend(_result["elements"])
            summary_data.append(
                (_result["invoice_number"], _result["patient_name"],
                 _result["invoice_amount"]))
            elements.append(PageBreak())
            if med_p and qs.medical_prescription and bool(qs.medical_prescription.file) \
                    and qs.medical_prescription.file.file.name not in already_added_images:
                elements.append(
                    Image(qs.medical_prescription.file,
                          width=469.88,
                          height=773.19))
                elements.append(PageBreak())
                already_added_images.append(
                    qs.medical_prescription.file.file.name)
    recap_data = _build_recap(summary_data)
    elements.extend(recap_data[0])
    elements.append(PageBreak())
    elements.extend(_build_final_page(recap_data[1], recap_data[2]))

    return elements
Ejemplo n.º 34
0
def generate_pdf(file):
    with open(file, 'r', encoding='utf-8') as file:
        data = file.read().replace('\n', '<br/>') \
            .replace('Juliet: <Media weggelaten> Neutral', 'Juliet: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/neutral_juliet.jpg"/>' + 1 * '<br/>') \
            .replace('Juliet: <Media weggelaten> Positive', 'Juliet: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/happy_juliet.jpg"/>' + 1 * '<br/>') \
            .replace('Juliet: <Media weggelaten> Negative', 'Juliet: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/angry_juliet.jpg"/>' + 1 * '<br/>') \
            .replace('Romeo: <Media weggelaten> Neutral', 'Romeo: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/neutral_romeo.jpg"/>' + 1 * '<br/>') \
            .replace('Romeo: <Media weggelaten> Positive', 'Romeo: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/happy_romeo.jpg"/>' + 1 * '<br/>') \
            .replace('Romeo: <Media weggelaten> Negative', 'Romeo: ' + 1 * "<br/>" + 11 * '<br/>' +
                     '<img src= "img_resized/angry_romeo.jpg"/>' + 1 * '<br/>')

    story = [
        DocAssign("currentFrame", "doc.frame.id"),
        DocAssign("currentPageTemplate", "doc.pageTemplate.id"),
        DocAssign("aW", "availableWidth"),
        DocAssign("aH", "availableHeight"),
        DocAssign("aWH", "availableWidth,availableHeight"),
        Paragraph("<b>Romeo and Juliet</b>" + 15 * '<br/>', title),
        Image('img/romeo_juliet.jpg', width=4 * inch, height=5 * inch),
        PageBreak(),
        Paragraph("<b>Introduction</b>", header),
        Paragraph(
            2 * '<br/>' +
            "<i>A 2019 interpretation of the famous love story in the form of a WhatsApp dialogue. Made for NaNoGenMo.</i>",
            normal),
        PageBreak(),
        Paragraph(data, normal)
    ]

    doc = SimpleDocTemplate("romeo_and_juliet.pdf")
    doc.build(story)
Ejemplo n.º 35
0
def createUrgentCoverPage(page_size=PAGE_SIZE_LETTER,
                            total_pages=1,
                            recipient_name='',
                            recipient_phone='',
                            recipient_fax='',
                            sender_name='',
                            sender_phone='',
                            sender_fax='',
                            sender_email='',
                            regarding='',
                            message='',
                            preserve_formatting=False,
                            output=None):

    s = getSampleStyleSheet()

    story = []
    i = Image(os.path.join(prop.image_dir, 'other', 'urgent_title.png'), width=424, height=92)
    i.hAlign = 'LEFT'
    story.append(i)
    story.append(Spacer(1, inch))
    story.append(HRFlowable(width='100%', color='black'))

    ps = ParagraphStyle(name='normal',
                        fontName='Times-Roman',
                        #fontName='STSong-Light',
                        #fontName='UMing',
                        fontSize=12)

    recipient_name_label = Paragraph("To:", ps)
    recipient_name_text = Paragraph(escape(recipient_name[:64]), ps)

    recipient_fax_label = Paragraph("Fax:", ps)
    recipient_fax_text = Paragraph(escape(recipient_fax[:64]), ps)

    recipient_phone_label = Paragraph("Phone:", ps)
    recipient_phone_text = Paragraph(escape(recipient_phone[:64]), ps)

    sender_name_label = Paragraph("From:", ps)
    sender_name_text = Paragraph(escape(sender_name[:64]), ps)

    sender_phone_label = Paragraph("Phone:", ps)
    sender_phone_text = Paragraph(escape(sender_phone[:64]), ps)

    sender_email_label = Paragraph("Email:", ps)
    sender_email_text = Paragraph(escape(sender_email[:64]), ps)

    regarding_label = Paragraph("Regarding:", ps)
    regarding_text = Paragraph(escape(regarding[:128]), ps)

    date_time_label = Paragraph("Date:", ps)
    date_time_text = Paragraph(strftime("%a, %d %b %Y %H:%M:%S (%Z)", localtime()), ps)

    total_pages_label = Paragraph("Total Pages:", ps)
    total_pages_text = Paragraph("%d" % total_pages, ps)

    data = [[recipient_name_label, recipient_name_text],
            [recipient_fax_label, recipient_fax_text],
            ['', ''],
            [sender_name_label, sender_name_text],
            [sender_phone_label, sender_phone_text],
            [sender_email_label, sender_email_text],
            ['', ''],
            [date_time_label, date_time_text],
            [total_pages_label, total_pages_text],
            [regarding_label, regarding_text],]

    LIST_STYLE = TableStyle([#('LINEABOVE', (0,0), (-1,0), 2, colors.black),
                             #('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
                             #('LINEBELOW', (0,-1), (-1,-1), 2, colors.black),
                             ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
                             ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                            ])


    story.append(Table(data, style=LIST_STYLE))
    story.append(HRFlowable(width='100%', color='black'))

    if message:
        MSG_STYLE = TableStyle([#('LINEABOVE', (0,0), (-1,0), 2, colors.black),
                                 #('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
                                 #('LINEBELOW', (0,-1), (-1,-1), 2, colors.black),
                                 ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
                                 ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                                 #('SPAN', (-2, 1), (-1, -1)),
                                ])

        #story.append(HRFlowable(width='100%', color='black'))
        story.append(Spacer(1, 0.5*inch))

#        if preserve_formatting:
#            message = '\n'.join(message[:2048].splitlines()[:32])
#
#            data = [#[Paragraph("Comments/Notes:", ps), ''],
#                    [Preformatted(escape(message), ps)],]
#        else:
#            data = [#[Paragraph("Comments/Notes:", ps), ''],
#                    [Paragraph(escape(message[:2048]), ps), ''],]
#
#        #story.append(HRFlowable(width='100%', color='black'))
#        #story.append(Table(data, style=MSG_STYLE))

        if preserve_formatting:
            message = '\n'.join(message[:2048].splitlines()[:32])
            story.append(Preformatted(escape(message), ps))
        else:
            story.append(Paragraph(escape(message), ps))


    if page_size == PAGE_SIZE_LETTER:
        pgsz = letter
    elif page_size == PAGE_SIZE_LEGAL:
        pgsz = legal
    else:
        pgsz = A4

    if output is None:
        f_fd, f = utils.make_temp_file()
    else:
        f = output

    doc = SimpleDocTemplate(f, pagesize=pgsz)
    doc.build(story)

    return f
Ejemplo n.º 36
0
def old_tables_test():
    from reportlab.lib.units import inch, cm
    from reportlab.platypus.flowables import Image, PageBreak, Spacer, XBox
    from reportlab.platypus.paragraph import Paragraph
    from reportlab.platypus.xpreformatted import XPreformatted
    from reportlab.platypus.flowables import Preformatted
    from reportlab.platypus.doctemplate import SimpleDocTemplate
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.platypus.tables import GRID_STYLE, BOX_STYLE, LABELED_GRID_STYLE, COLORED_GRID_STYLE, LIST_STYLE, LongTable
    rowheights = (24, 16, 16, 16, 16)
    rowheights2 = (24, 16, 16, 16, 30)
    colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
    data = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    data2 = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats\nLarge', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    lst = []
    lst.append(Paragraph("Tables", styleSheet['Heading1']))
    lst.append(Paragraph(__doc__, styleSheet['BodyText']))
    lst.append(Paragraph("The Tables (shown in different styles below) were created using the following code:", styleSheet['BodyText']))
    lst.append(Preformatted("""
    colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
    rowheights = (24, 16, 16, 16, 16)
    data = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun',
           'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159,
             888, '1,298', 832, 453, '1,344','2,843')
        )
    t = Table(data, colwidths, rowheights)
    """, styleSheet['Code'], dedent=4))
    lst.append(Paragraph("""
    You can then give the Table a TableStyle object to control its format. The first TableStyle used was
    created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
GRID_STYLE = TableStyle(
    [('GRID', (0,0), (-1,-1), 0.25, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))
    lst.append(Paragraph("""
    TableStyles are created by passing in a list of commands. There are two types of commands - line commands
    and cell formatting commands. In all cases, the first three elements of a command are the command name,
    the starting cell and the ending cell.
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    Line commands always follow this with the weight and color of the desired lines. Colors can be names,
    or they can be specified as a (R,G,B) tuple, where R, G and B are floats and (0,0,0) is black. The line
    command names are: GRID, BOX, OUTLINE, INNERGRID, LINEBELOW, LINEABOVE, LINEBEFORE
    and LINEAFTER. BOX and OUTLINE are equivalent, and GRID is the equivalent of applying both BOX and
    INNERGRID.
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    Cell formatting commands are:
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    FONT - takes fontname, fontsize and (optional) leading.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    TEXTCOLOR - takes a color name or (R,G,B) tuple.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    ALIGNMENT (or ALIGN) - takes one of LEFT, RIGHT, CENTRE (or CENTER) or DECIMAL.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    LEFTPADDING - defaults to 6.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    RIGHTPADDING - defaults to 6.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    BOTTOMPADDING - defaults to 3.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    A tablestyle is applied to a table by calling Table.setStyle(tablestyle).
    """, styleSheet['BodyText']))
    t = Table(data, colwidths, rowheights)
    t.setStyle(GRID_STYLE)
    lst.append(PageBreak())
    lst.append(Paragraph("This is GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)

    t = Table(data, colwidths, rowheights)
    t.setStyle(BOX_STYLE)
    lst.append(Paragraph("This is BOX_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
BOX_STYLE = TableStyle(
    [('BOX', (0,0), (-1,-1), 0.50, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    t.setStyle(LABELED_GRID_STYLE)
    lst.append(Paragraph("This is LABELED_GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    t = Table(data2, colwidths, rowheights2)
    t.setStyle(LABELED_GRID_STYLE)
    lst.append(Paragraph("This is LABELED_GRID_STYLE ILLUSTRATES EXPLICIT LINE SPLITTING WITH NEWLINE (different heights and data)\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
LABELED_GRID_STYLE = TableStyle(
    [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
     ('BOX', (0,0), (-1,-1), 2, colors.black),
     ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
     ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))
    lst.append(PageBreak())

    t = Table(data, colwidths, rowheights)
    t.setStyle(COLORED_GRID_STYLE)
    lst.append(Paragraph("This is COLORED_GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
COLORED_GRID_STYLE = TableStyle(
    [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
     ('BOX', (0,0), (-1,-1), 2, colors.red),
     ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
     ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    t.setStyle(LIST_STYLE)
    lst.append(Paragraph("This is LIST_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
LIST_STYLE = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    ts = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 3, colors.green,'butt'),
     ('LINEBELOW', (0,-1), (-1,-1), 1, colors.white,'butt'),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
     ('TEXTCOLOR', (0,1), (0,-1), colors.red),
     ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
    )
    t.setStyle(ts)
    lst.append(Paragraph("This is a custom style\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
   ts = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 3, colors.green,'butt'),
     ('LINEBELOW', (0,-1), (-1,-1), 1, colors.white,'butt'),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
     ('TEXTCOLOR', (0,1), (0,-1), colors.red),
     ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
    )
    """, styleSheet['Code']))
    data = (
        ('', 'Jan\nCold', 'Feb\n', 'Mar\n','Apr\n','May\n', 'Jun\nHot', 'Jul\n', 'Aug\nThunder', 'Sep\n', 'Oct\n', 'Nov\n', 'Dec\n'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    c = list(colwidths)
    c[0] = None
    c[8] = None
    t = Table(data, c, [None]+list(rowheights[1:]))
    t.setStyle(LIST_STYLE)
    lst.append(Paragraph("""
        This is a LIST_STYLE table with the first rowheight set to None ie automatic.
        The top row cells are split at a newline '\\n' character. The first and August
        column widths were also set to None.
    """, styleSheet['BodyText']))
    lst.append(t)

    lst.append(Paragraph("""
        This demonstrates a number of features useful in financial statements. The first is decimal alignment;
        with ALIGN=DECIMAL the numbers align on the points; and the points are aligned based on
        the RIGHTPADDING, which is usually 3 points so you should set it higher.  The second is multiple lines;
        one can specify double or triple lines and control the separation if desired. Finally, the coloured
        negative numbers were (we regret to say) done in the style; we don't have a way to conditionally
        format numbers based on value yet.
    """, styleSheet['BodyText']))


    t = Table([[u'Corporate Assets','Amount'],
               ['Fixed Assets','1,234,567.89'],
               ['Company Vehicle','1,234.8901'],
               ['Petty Cash','42'],
               [u'Intellectual Property\u00ae','(42,078,231.56)'],
               ['Overdraft','(12,345)'],
               ['Boardroom Flat Screen','60 inches'],
               ['Net Position','Deep Sh*t.Really']
               ],
              [144,72])

    ts = TableStyle(
        [#first the top row
         ('ALIGN', (1,1), (-1,-1), 'CENTER'),
         ('LINEABOVE', (0,0), (-1,0), 1, colors.purple),
         ('LINEBELOW', (0,0), (-1,0), 1, colors.purple),
         ('FONT', (0,0), (-1,0), 'Times-Bold'),

        #bottom row has a line above, and two lines below
         ('LINEABOVE', (0,-1), (-1,-1), 1, colors.purple),  #last 2 are count, sep
         ('LINEBELOW', (0,-1), (-1,-1), 0.5, colors.purple, 1, None, None, 4,1),
         ('LINEBELOW', (0,-1), (-1,-1), 1, colors.red),
         ('FONT', (0,-1), (-1,-1), 'Times-Bold'),

        #numbers column
         ('ALIGN', (1,1), (-1,-1), 'DECIMAL'),
         ('RIGHTPADDING', (1,1), (-1,-1), 36),
         ('TEXTCOLOR', (1,4), (1,4), colors.red),

        #red cell         
        ]
        )

    t.setStyle(ts)
    lst.append(t)
    lst.append(Spacer(36,36))    
    lst.append(Paragraph("""
        The red numbers should be aligned LEFT &amp; BOTTOM, the blue RIGHT &amp; TOP
        and the green CENTER &amp; MIDDLE.
    """, styleSheet['BodyText']))
    XY  =   [['X00y', 'X01y', 'X02y', 'X03y', 'X04y'],
            ['X10y', 'X11y', 'X12y', 'X13y', 'X14y'],
            ['X20y', 'X21y', 'X22y', 'X23y', 'X24y'],
            ['X30y', 'X31y', 'X32y', 'X33y', 'X34y']]
    t=Table(XY, 5*[0.6*inch], 4*[0.6*inch])
    t.setStyle([('ALIGN',(1,1),(-2,-2),'LEFT'),
                ('TEXTCOLOR',(1,1),(-2,-2),colors.red),

                ('VALIGN',(0,0),(1,-1),'TOP'),
                ('ALIGN',(0,0),(1,-1),'RIGHT'),
                ('TEXTCOLOR',(0,0),(1,-1),colors.blue),

                ('ALIGN',(0,-1),(-1,-1),'CENTER'),
                ('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
                ('TEXTCOLOR',(0,-1),(-1,-1),colors.green),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                ])
    lst.append(t)
    data = [('alignment', 'align\012alignment'),
            ('bulletColor', 'bulletcolor\012bcolor'),
            ('bulletFontName', 'bfont\012bulletfontname'),
            ('bulletFontSize', 'bfontsize\012bulletfontsize'),
            ('bulletIndent', 'bindent\012bulletindent'),
            ('firstLineIndent', 'findent\012firstlineindent'),
            ('fontName', 'face\012fontname\012font'),
            ('fontSize', 'size\012fontsize'),
            ('leading', 'leading'),
            ('leftIndent', 'leftindent\012lindent'),
            ('rightIndent', 'rightindent\012rindent'),
            ('spaceAfter', 'spaceafter\012spacea'),
            ('spaceBefore', 'spacebefore\012spaceb'),
            ('textColor', 'fg\012textcolor\012color')]
    t = Table(data)
    t.setStyle([
            ('VALIGN',(0,0),(-1,-1),'TOP'),
            ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
            ('BOX', (0,0), (-1,-1), 0.25, colors.black),
            ])
    lst.append(t)
    t = Table([ ('Attribute', 'Synonyms'),
                ('alignment', 'align, alignment'),
                ('bulletColor', 'bulletcolor, bcolor'),
                ('bulletFontName', 'bfont, bulletfontname'),
                ('bulletFontSize', 'bfontsize, bulletfontsize'),
                ('bulletIndent', 'bindent, bulletindent'),
                ('firstLineIndent', 'findent, firstlineindent'),
                ('fontName', 'face, fontname, font'),
                ('fontSize', 'size, fontsize'),
                ('leading', 'leading'),
                ('leftIndent', 'leftindent, lindent'),
                ('rightIndent', 'rightindent, rindent'),
                ('spaceAfter', 'spaceafter, spacea'),
                ('spaceBefore', 'spacebefore, spaceb'),
                ('textColor', 'fg, textcolor, color')])
    t.repeatRows = 1
    t.setStyle([
                ('FONT',(0,0),(-1,1),'Times-Bold',10,12),
                ('FONT',(0,1),(-1,-1),'Courier',8,8),
                ('VALIGN',(0,0),(-1,-1),'MIDDLE'),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                ('BACKGROUND', (0, 0), (-1, 0), colors.green),
                ('BACKGROUND', (0, 1), (-1, -1), colors.pink),
                ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
                ('ALIGN', (0, 1), (0, -1), 'LEFT'),
                ('ALIGN', (-1, 1), (-1, -1), 'RIGHT'),
                ('FONT', (0, 0), (-1, 0), 'Times-Bold', 12),
                ('ALIGN', (1, 1), (1, -1), 'CENTER'),
                ])
    lst.append(t)
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 5,6),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.blue),]))
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 10,12),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.black),]))
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 20,24),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.red),]))
    lst.append(PageBreak())
    data=  [['00', '01', '02', '03', '04'],
            ['10', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34']]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ])
    lst.append(Paragraph("Illustrating splits: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,30)", styleSheet['BodyText']))
    for s in t.split(4*inch,30):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,36)", styleSheet['BodyText']))
    for s in t.split(4*inch,36):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    lst.append(PageBreak())
    data=  [['00', '01', '02', '03', '04'],
            ['', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '', '33', '34']]
    sty=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('SPAN',(0,0),(0,1)),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('SPAN',(2,2),(2,3)),
                    ]
    t=Table(data,style=sty)
    lst.append(Paragraph("Illustrating splits with spans: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,30)", styleSheet['BodyText']))
    for s in t.split(4*inch,30):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,36)", styleSheet['BodyText']))
    for s in t.split(4*inch,36):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    data=  [['00', '01', '02', '03', '04'],
            ['', '11', '12', '13', ''],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '', '33', ''],
            ['40', '41', '', '43', '44']]
    sty=[
        ('GRID',(0,0),(-1,-1),0.5,colors.grey),
        ('GRID',(1,1),(-2,-2),1,colors.green),
        ('BOX',(0,0),(1,-1),2,colors.red),
        ('BOX',(0,0),(-1,-1),2,colors.black),
        ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
        ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
        ('BACKGROUND', (0, 0), (0, 1), colors.pink),
        ('SPAN',(0,0),(0,1)),
        ('BACKGROUND',(-2,1),(-1,1),colors.palegreen),
        ('SPAN',(-2,1),(-1,1)),
        ('BACKGROUND',(-2,3),(-1,3),colors.yellow),
        ('SPAN',(-2,3),(-1,3)),
        ('BACKGROUND', (2, 3), (2, 4), colors.orange),
        ('SPAN',(2,3),(2,4)),
        ]

    t=Table(data,style=sty,repeatRows=2)
    lst.append(Paragraph("Illustrating splits with spans and repeatRows: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    if  1:
        lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,30)", styleSheet['BodyText']))
        for s in t.split(4*inch,30):
            lst.append(s)
            lst.append(Spacer(0,6))
        lst.append(Spacer(0,6))
        lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,36)", styleSheet['BodyText']))
        for s in t.split(4*inch,36):
            lst.append(s)
            lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    lst.append(PageBreak())
    from reportlab.lib.testutils import testsFolder
    I = Image(os.path.join(os.path.dirname(testsFolder),'src','tools','pythonpoint','demos','leftlogo.gif'))
    I.drawHeight = 1.25*inch*I.drawHeight / I.drawWidth
    I.drawWidth = 1.25*inch
    #I.drawWidth = 9.25*inch #uncomment to see better messaging
    P = Paragraph("<para align=center spaceb=3>The <b>ReportLab Left <font color=red>Logo</font></b> Image</para>", styleSheet["BodyText"])
    B = TableBarChart()
    BP = Paragraph("<para align=center spaceb=3>A bar chart in a cell.</para>", styleSheet["BodyText"])

    data=  [['A', 'B', 'C', Paragraph("<b>A pa<font color=red>r</font>a<i>graph</i></b><super><font color=yellow>1</font></super>",styleSheet["BodyText"]), 'D'],
            ['00', '01', '02', [I,P], '04'],
            ['10', '11', '12', [I,P], '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34'],
            ['40', '41', '42', [B,BP], '44']]

    t=Table(data,style=[('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('GRID',(0,0),(-1,-1),0.5,colors.black),
                    ('VALIGN',(3,0),(3,0),'BOTTOM'),
                    ('BACKGROUND',(3,0),(3,0),colors.limegreen),
                    ('BACKGROUND',(3,1),(3,1),colors.khaki),
                    ('ALIGN',(3,1),(3,1),'CENTER'),
                    ('BACKGROUND',(3,2),(3,2),colors.beige),
                    ('ALIGN',(3,2),(3,2),'LEFT'),
                    ])

    t._argW[3]=1.5*inch
    lst.append(t)

    # now for an attempt at column spanning.
    lst.append(PageBreak())
    data=  [['A', 'BBBBB', 'C', 'D', 'E'],
            ['00', '01', '02', '03', '04'],
            ['10', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34']]
    sty = [
            ('ALIGN',(0,0),(-1,-1),'CENTER'),
            ('VALIGN',(0,0),(-1,-1),'TOP'),
            ('GRID',(0,0),(-1,-1),1,colors.green),
            ('BOX',(0,0),(-1,-1),2,colors.red),

            #span 'BBBB' across middle 3 cells in top row
            ('SPAN',(1,0),(3,0)),
            #now color the first cell in this range only,
            #i.e. the one we want to have spanned.  Hopefuly
            #the range of 3 will come out khaki.
            ('BACKGROUND',(1,0),(1,0),colors.khaki),

            ('SPAN',(0,2),(-1,2)),


            #span 'AAA'down entire left column
            ('SPAN',(0,0), (0, 1)),
            ('BACKGROUND',(0,0),(0,0),colors.cyan),
            ('LINEBELOW', (0,'splitlast'), (-1,'splitlast'), 1, colors.white,'butt'),
           ]
    t=Table(data,style=sty, colWidths = [20] * 5, rowHeights = [20]*5)
    lst.append(t)

    # now for an attempt at percentage widths
    lst.append(Spacer(18,18))
    lst.append(Paragraph("This table has colWidths=5*['14%']!", styleSheet['BodyText']))
    t=Table(data,style=sty, colWidths = ['14%'] * 5, rowHeights = [20]*5)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph("This table has colWidths=['14%','10%','19%','22%','*']!", styleSheet['BodyText']))
    t=Table(data,style=sty, colWidths = ['14%','10%','19%','22%','*'], rowHeights = [20]*5)
    lst.append(t)

    # Mike's test example
    lst.append(Spacer(18,18))
    lst.append(Paragraph('Mike\'s Spanning Example', styleSheet['Heading1']))
    data=  [[Paragraph('World Domination: The First Five Years', styleSheet['BodyText']), ''],
            [Paragraph('World <font color="green">Domination</font>: The First Five Years', styleSheet['BodyText']),''],
            [Paragraph('World Domination: The First Five Years', styleSheet['BodyText']), ''],
            ]
    t=Table(data, style=[('SPAN',(0,0),(1,0)),('SPAN',(0,1),(1,1)),('SPAN',(0,2),(1,2)),], colWidths = [3*cm,8*cm], rowHeights = [None]*3)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph('Mike\'s Non-spanning Example', styleSheet['Heading1']))
    data=  [[Paragraph('World Domination: The First Five Years', styleSheet['BodyText'])],
            [Paragraph('World <font color="magenta">Domination</font>: The First Five Years', styleSheet['BodyText'])],
            [Paragraph('World Domination: The First Five Years', styleSheet['BodyText'])],
            ]
    t=Table(data, style=[], colWidths = [11*cm], rowHeights = [None]*3)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph('xpre example', styleSheet['Heading1']))
    data=  [    [
                XPreformatted('Account Details', styleSheet['Heading3']),
                '', XPreformatted('Client Details', styleSheet['Heading3']),
                ],  #end of row 0
            ]
    t=Table(data, style=[], colWidths = [80,230.0,80], rowHeights = [None]*1)
    lst.append(t)

    lst.append(PageBreak())

    lst.append(Paragraph('Trying colour cycling in background', styleSheet['Heading1']))
    lst.append(Paragraph("This should alternate pale blue and uncolored by row", styleSheet['BodyText']))
    data=  [['001', '01', '02', '03', '04', '05'],
            ['002', '01', '02', '03', '04', '05'],
            ['003', '01', '02', '03', '04', '05'],
            ['004', '01', '02', '03', '04', '05'],
            ['005', '01', '02', '03', '04', '05'],
            ['006', '01', '02', '03', '04', '05'],
            ['007', '01', '02', '03', '04', '05'],
            ['008', '01', '02', '03', '04', '05'],
            ['009', '01', '02', '03', '04', '05'],
            ['010', '01', '02', '03', '04', '05'],

            ]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('ROWBACKGROUNDS', (0, 0), (-1, -1), (0xD0D0FF, None)),
                    ])
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("And this should pale blue, pale pink and None by column", styleSheet['BodyText']))
    data=  [['001', '01', '02', '03', '04', '05'],
            ['002', '01', '02', '03', '04', '05'],
            ['003', '01', '02', '03', '04', '05'],
            ['004', '01', '02', '03', '04', '05'],
            ['005', '01', '02', '03', '04', '05'],
            ['006', '01', '02', '03', '04', '05'],
            ['007', '01', '02', '03', '04', '05'],
            ['008', '01', '02', '03', '04', '05'],
            ['009', '01', '02', '03', '04', '05'],
            ['010', '01', '02', '03', '04', '05'],

            ]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('COLBACKGROUNDS', (0, 0), (-1, -1), (0xD0D0FF, 0xFFD0D0, None)),
                    ])
    lst.append(t)

    lst.append(PageBreak())
    lst.append(Paragraph("This spanning example illustrates automatic removal of grids and lines in spanned cells!", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    data=  [['Top\nLeft', '', '02', '03', '04', '05', '06', '07'],
            ['', '', '12', 'Span (3,1) (6,2)', '','','','17'],
            ['20', '21', '22', '', '','','','27'],
            ['30', '31', '32', '33', '34','35','36','37'],
            ['40', 'In The\nMiddle', '', '', '44','45','46','47'],
            ['50', '', '', '', '54','55','56','57'],
            ['60', '', '', '','64', '65', 'Bottom\nRight', ''],
            ['70', '71', '72', '73','74', '75', '', '']]
    t=Table(data,style=[
            ('GRID',(0,0),(-1,-1),0.5,colors.grey),
            ('BACKGROUND',(0,0),(1,1),colors.palegreen),
            ('SPAN',(0,0),(1,1)),
            ('BACKGROUND',(-2,-2),(-1,-1), colors.pink),
            ('SPAN',(-2,-2),(-1,-1)),
            ('SPAN',(1,4),(3,6)),
            ('BACKGROUND',(1,4),(3,6), colors.lightblue),
            ('SPAN',(3,1),(6,2)),
            ('BACKGROUND',(3,1),(6,2), colors.peachpuff),
            ('VALIGN',(3,1),(6,2),'TOP'),
            ('LINEABOVE', (0,2),(-1,2), 1, colors.black, 0, None, None, 2, 2),
            ('LINEBEFORE', (3,0),(3,-1), 1, colors.black, 0, None, None, 2, 2),
            ])
    lst.append(t)

    lst.append(PageBreak())

    lst.append(Paragraph("und jetzt noch eine Tabelle mit 5000 Zeilen:", styleSheet['BodyText']))
    sty = [ ('GRID',(0,0),(-1,-1),1,colors.green),
            ('BOX',(0,0),(-1,-1),2,colors.red),
           ]
    data = [[str(i), Paragraph("xx "* (i%10), styleSheet["BodyText"]), Paragraph("blah "*(i%40), styleSheet["BodyText"])] for i in range(500)]
    t=LongTable(data, style=sty, colWidths = [50,100,200])
    lst.append(t)

    #Yuan Hong's bug tester
    lst.append(PageBreak())
    lst.append(Paragraph('Yian Hong\'s Bug Case (should not blow up)', styleSheet['Heading2']))
    data = ([['Col1', 'Col2', 'Col3', 'Col4', 'Col5']]+
                [['01', Paragraph('This is cell one that contains a paragraph.', styleSheet['Normal']), '02', '03', '04']
                    for i in range(50)])

    t = Table(data, ['20%']*5, repeatRows=1)
    t.setStyle(TableStyle([
        ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
        ('BOX', (0,0), (-1,-1), 0.25, colors.black),
        ('SPAN', (0,50), (-2,50)),
        ]))

    lst.append(t)
    lst.append(PageBreak())

    #Volker Haas' example extended
    #the optimal row heights are the solution of an LP similar to
    #
    #Objective function
    #   min: 3*h0+3*h1+3*h2+2*h3;
    #
    #constraints
    #   h0>=12;
    #   h1>=12;
    #   h2>=12;
    #   h3>=12;
    #   h0+h1+h2>=48;
    #   h0+h1>=12;
    #   h2+h3>=60;
    #
    #the solution H=[12,12,24,36]
    def makeTable(x,y):
        return Table([
                ['00', '01', '02', '03', '04', '05\nline2\nline3\nline4'],
                ['', '11', '12', x, '',''],
                ['20', '21', y, '23', '24',''],
                ['30', '31', '', '33', '34','35'],
                ],
                style=[
                    ('TOPPADDING',(0,0),(-1,-1),0),
                    ('BOTTOMPADDING',(0,0),(-1,-1),0),
                    ('RIGHTPADDING',(0,0),(-1,-1),0),
                    ('LEFTPADDING',(0,0),(-1,-1),0),
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('SPAN',(0,0),(0,1)),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('SPAN',(2,2),(2,3)),
                    ('SPAN',(3,1),(4,1)),
                    ('SPAN',(5,0),(5,2)),
                ])
    p_style= ParagraphStyle('Normal')
    lst.append(makeTable(
            Paragraph('This is a string',p_style),
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))

    lst.append(Spacer(10,10))
    lst.append(makeTable(
            XPreformatted('This is a string',p_style),
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))
    lst.append(Spacer(10,10))
    lst.append(makeTable(
            'This is a string',
            '22\nblub\nasfd\nafd\nasdfs',
            ))
    lst.append(Spacer(10,10))
    lst.append(makeTable(
            'This is a string',
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))
    SimpleDocTemplate(outputfile('test_platypus_tables_2.pdf'), showBoundary=1).build(lst)
Ejemplo n.º 37
0
    def Impression(self, listeActivites, listePeriodes):
        # Création du PDF
        self.taille_page = A4
        self.orientation = "PORTRAIT"
        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))
                                    
        # Récupération des individus grâce à leurs consommations
        self.EcritStatusBar(_(u"Recherche des individus..."))
        DB = GestionDB.DB() 
        req = """SELECT individus.IDindividu, 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()
        DB.Close() 
        if len(listeIndividus) == 0 :
            dlg = wx.MessageDialog(self, _(u"Aucun individu n'a été trouvé avec les paramètres spécifiés !"), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.EcritStatusBar(u"")
            return

        dictIndividus = {}
        listeIDindividus = []
        
        dictAnniversaires = {} 
        
        self.EcritStatusBar(_(u"Recherche des dates de naissance..."))
        for IDindividu, IDcivilite, nom, prenom, date_naiss in listeIndividus :
            if date_naiss != None : 
                date_naiss = DateEngEnDateDD(date_naiss)
                age = GetAge(date_naiss)
                jour = date_naiss.day
                mois = date_naiss.month
                
                # Mémorisation de l'individu
                dictIndividus[IDindividu] = { 
                    "IDcivilite" : IDcivilite, "nom" : nom, "prenom" : prenom, 
                    "age" : age, "date_naiss" : date_naiss,
                    }
                
                # Mémorisation du IDindividu
                if dictAnniversaires.has_key(mois) == False : 
                    dictAnniversaires[mois] = {} 
                if dictAnniversaires[mois].has_key(jour) == False : 
                    dictAnniversaires[mois][jour] = []
                dictAnniversaires[mois][jour].append(IDindividu)
                
                if IDindividu not in listeIDindividus :
                    listeIDindividus.append(IDindividu) 
                
        # Récupération des photos individuelles
        dictPhotos = {}
        taillePhoto = 128
        if self.ctrl_photos.GetSelection() == 0 : tailleImageFinal = 16
        if self.ctrl_photos.GetSelection() == 1 : tailleImageFinal = 32
        if self.ctrl_photos.GetSelection() == 2 : tailleImageFinal = 64
        if self.check_photos.GetValue() == True :
            index = 0
            for IDindividu in listeIDindividus :
                self.EcritStatusBar(_(u"Recherche des photos... %d/%d") % (index, len(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
                
                index += 1
            
        # ---------------- Création du PDF -------------------
        self.EcritStatusBar(_(u"Création du PDF...")) 
        
        # Initialisation du PDF
        nomDoc = FonctionsPerso.GenerationNomDoc("ANNIVERSAIRES", "pdf")
        if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\")
        doc = BaseDocTemplate(nomDoc, pagesize=(self.largeur_page, self.hauteur_page), topMargin=30, bottomMargin=30, showBoundary=False)
        doc.addPageTemplates(MyPageTemplate(pageSize=(self.largeur_page, self.hauteur_page)))
        story = []
                        
        # Mois
        listeMois = dictAnniversaires.keys()
        listeMois.sort() 
        for numMois in listeMois :
            
            # Mémorise le numéro de mois pour le titre de la page
            nomMois = LISTE_NOMS_MOIS[numMois-1]
            story.append(DocAssign("numMois", numMois))

            # Jours
            dictJours = dictAnniversaires[numMois]
            listeJours = dictJours.keys() 
            listeJours.sort() 
            for numJour in listeJours :                                
                # Initialisation du tableau
                dataTableau = []
                largeursColonnes = []
                                    
                # Recherche des entêtes de colonnes :
                if self.check_photos.GetValue() == True :
                    largeursColonnes.append(tailleImageFinal+6)
                
                # Colonne nom de l'individu
                largeursColonnes.append(LARGEUR_COLONNE-sum(largeursColonnes))
                
                # Label numéro de jour
                ligne = []
                ligne.append(str(numJour))
                if self.check_photos.GetValue() == True :
                    ligne.append(u"")
                dataTableau.append(ligne)
                
                # Individus
                listeIndividus = dictAnniversaires[numMois][numJour]
                
                for IDindividu in listeIndividus :
                    ligne = []
                    
                    # Photo
                    if self.check_photos.GetValue() == True and IDindividu in dictPhotos :
                        img = dictPhotos[IDindividu]
                        ligne.append(img)
                    
                    # Nom
                    nom = dictIndividus[IDindividu]["nom"]
                    prenom = dictIndividus[IDindividu]["prenom"]
                    ligne.append(u"%s %s" % (nom, prenom))
                    
                    # Ajout de la ligne individuelle dans le tableau
                    dataTableau.append(ligne)
             
                couleurFondJour = (0.8, 0.8, 1) # Vert -> (0.5, 1, 0.2)
                couleurFondTableau = (1, 1, 1)
                
                style = TableStyle([
                        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases
                        ('BACKGROUND', (0,0), (-1,-1), couleurFondTableau), # Donne la couleur de fond du titre de groupe
                        
                        ('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), (-1,-1), 'CENTRE'), # Centre les cases
                        
                        ('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), couleurFondJour), # 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, 10))
                    
            # Saut de page après un mois
            story.append(PageBreak())
            
        # Enregistrement du PDF
        doc.build(story)
        
        # Affichage du PDF
        FonctionsPerso.LanceFichierExterne(nomDoc)
        
        self.EcritStatusBar(u"") 
 def image(self, name, width, height, halign='CENTER'):
     im = Image(name, width=width, height=height)
     im.hAlign = halign
     self._store_flowable(im)
Ejemplo n.º 39
0
class F116PdfOld(BasePdf):
    
    def __init__(self, data, debug=False):
        super(F116PdfOld, self).__init__(data, debug)
        if data:
            self.lside_data = data[0]
            self.rside_data = data[1]

    def create_pdf_file(self, file_name, page_size=landscape(A4)):
        super(F116PdfOld, self).create_pdf_file(file_name, page_size)
    
    def render_page1_image(self):
        A4_Width, A4_Height = A4
        self.im = Image(_self_path+ '/' + u'post1.JPG',width=A4_Height, height=A4_Width)
        self.im.drawOn(self.pdf, self.x(0), self.y(0))

    def render_page2_image(self):
        A4_Width, A4_Height = A4
        self.im = Image(_self_path+ '/' + u'post2.JPG',width=A4_Height, height=A4_Width)
        self.im.drawOn(self.pdf, self.x(0), self.y(0))


    def render_page1_oneside_data(self, side_data):
        self.pdf.setFont('DejaVuSans', 8)

        #money
        self.pdf.setFont('DejaVuSans', 12)
        self.pdf.drawString(self.x(2.05*cm), self.y(15.4*cm), side_data.sum + u" руб. 00 коп.")
        self.pdf.drawString(self.x(3.53*cm), self.y(4*cm), side_data.sum)
        
        #to
        self.pdf.setFont('DejaVuSans', 8)
        #name
        self.drawClippingString(side_data.to_name, self.x(3.12*cm), self.y(13.8*cm), 5.1*cm, 0.5*cm)
        #address - if need split
        if len(side_data.to_address) >= 33: # 33chars for font size 8
            #split to 2 line
            self.drawClippingString(side_data.to_address[:33], self.x(3.12*cm), self.y(13.35*cm), 5.1*cm, 0.5*cm)
            #if len(side_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString(side_data.to_address[33:], self.x(2.02*cm), self.y(12.95*cm), 6.1*cm, 0.5*cm)
        else:
            self.drawClippingString(side_data.to_address, self.x(3.12*cm), self.y(13.35*cm), 5.1*cm, 0.5*cm)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(5.39*cm), self.y(12.55*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(8)
        zip_code.textLine(side_data.to_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)
        
        #from
        #name
        self.drawClippingString(side_data.from_name, self.x(3.5*cm), self.y(12*cm), 9.05*cm, 0.5*cm)
        #address - if need split
        if len(side_data.from_address) >= 60: # chars for font size 8
            #split to 2 line
            self.drawClippingString(side_data.from_address[:60], self.x(3.12*cm), self.y(11.5*cm), 9.6*cm, 0.5*cm)
            #if len(side_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString(side_data.from_address[60:], self.x(2.03*cm), self.y(11*cm), 7.5*cm, 0.5*cm)
        else:
            self.drawClippingString(side_data.from_address, self.x(3.12*cm), self.y(11.5*cm), 5.1*cm, 0.5*cm)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(9.77*cm), self.y(11.04*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(8)
        zip_code.textLine(side_data.from_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)


        #to_down
        self.pdf.setFont('DejaVuSans', 8)
        #name
        self.drawClippingString(side_data.to_name, self.x(3.12*cm), self.y(3.3*cm), 9.4*cm, 0.5*cm)
        #address - if need split
        if len(side_data.to_address) >= 60: # 60chars for font size 8
            #split to 2 line
            self.drawClippingString(side_data.to_address[:60], self.x(3.2*cm), self.y(2.75*cm), 9.4*cm, 0.5*cm)
            #if len(side_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString(side_data.to_address[60:], self.x(2*cm), self.y(2.28*cm), 7.5*cm, 0.5*cm)
        else:
            self.drawClippingString(side_data.to_address, self.x(3.2*cm), self.y(2.75*cm), 9.4*cm, 0.5*cm)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(9.77*cm), self.y(2.18*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(8)
        zip_code.textLine(side_data.to_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)
        
        #passport data
        self.pdf.setFontSize(8)
        self.drawClippingString2(side_data.passport_type , self.x(3.9*cm), self.y(9.6*cm), 8)
        self.drawClippingString2(side_data.passport_series , self.x(6.35*cm), self.y(9.6*cm), 4)
        self.drawClippingString2(side_data.passport_number , self.x(7.5*cm), self.y(9.6*cm), 6)
        self.drawClippingString2(side_data.passport_dt1 , self.x(10.5*cm), self.y(9.6*cm), 5)
        self.drawClippingString2(side_data.passport_dt2 , self.x(12.2*cm), self.y(9.6*cm), 2)
        self.drawClippingString2(side_data.passport_by , self.x(2.1*cm), self.y(9.1*cm), 65)
        
     
    def _make_page1_pdf(self, file_name=u'page1.pdf'):
        self.create_pdf_file(file_name, page_size=landscape(A4))
        self.set_cyrillic_font()
        self.render_page1_image()
        self.render_page1_oneside_data(self.lside_data)
        self.base_x += 14.8*cm
        self.base_y += -0.14*cm
        self.render_page1_oneside_data(self.rside_data)
        self.pdf.showPage() # page end
        #page 2
        self.base_x = 0
        self.base_y = 0
        self.render_page2_image()
        self.end_page()
        self.write_pdf_file()
        
    def make_pdf_file(self, file_name=u'F116.pdf'):
        self._make_page1_pdf(file_name)
    def test1(self):
        "This makes one long multi-page paragraph."

        # Build story.
        story = []
        styleSheet = getSampleStyleSheet()
        h3 = styleSheet['Heading3']
        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.We can do greek letters <greek>mDngG</greek>. This should be a
u with a dieresis on top &lt;unichar code=0xfc/&gt;="<unichar code="0xfc"/>" and this &amp;#xfc;="&#xfc;" and this \\xc3\\xbc="\xc3\xbc". On the other hand this
should be a pound sign &amp;pound;="&pound;" and this an alpha &amp;alpha;="&alpha;". You can have links in the page <link href="http://www.reportlab.com" color="blue">ReportLab</link> &amp; <a href="http://www.reportlab.org" color="green">ReportLab.org</a>.
Use scheme "pdf:" to indicate an external PDF link, "http:", "https:" to indicate an external link eg something to open in
your browser. If an internal link begins with something that looks like a scheme, precede with "document:". <strike>This text should have a strike through it.</strike>
'''
        from reportlab.platypus.flowables import ImageAndFlowables, Image
        from reportlab.lib.testutils import testsFolder
        gif = os.path.join(testsFolder,'pythonpowered.gif')
        heading = Paragraph('This is a heading',h3)
        story.append(ImageAndFlowables(Image(gif),[heading,Paragraph(text,bt)]))
        phrase = 'This should be a paragraph spanning at least three pages. '
        description = ''.join([('%d: '%i)+phrase for i in xrange(250)])
        story.append(ImageAndFlowables(Image(gif),[heading,Paragraph(description, bt)],imageSide='left'))
        story.append(NextPageTemplate('special'))
        story.append(PageBreak())
        VERA = ('Vera','VeraBd','VeraIt','VeraBI')
        for v in VERA:
            registerFont(TTFont(v,v+'.ttf'))
        registerFontFamily(*(VERA[:1]+VERA))
        story.append(ImageAndFlowables(
                        Image(gif,width=280,height=120),
                        Paragraph('''<font name="Vera">The <b>concept</b> of an <i>integrated</i> one <b><i>box</i></b> solution for <i><b>advanced</b></i> voice and
data applications began with the introduction of the IMACS. The
IMACS 200 carries on that tradition with an integrated solution
optimized for smaller port size applications that the IMACS could not
economically address. An array of the most popular interfaces and
features from the IMACS has been bundled into a small 2U chassis
providing the ultimate in ease of installation.</font>''',
                        style=ParagraphStyle(
                                name="base",
                                fontName="Helvetica",
                                leading=12,
                                leftIndent=0,
                                firstLineIndent=0,
                                spaceBefore = 9.5,
                                fontSize=9.5,
                                )
                            ),
                    imageSide='left',
                    )
                )
        story.append(ImageAndFlowables(
                        Image(gif,width=240,height=120),
                        Paragraph('''The concept of an integrated one box solution for advanced voice and
data applications began with the introduction of the IMACS. The
IMACS 200 carries on that tradition with an integrated solution
optimized for smaller port size applications that the IMACS could not
economically address. An array of the most popular interfaces and
features from the IMACS has been bundled into a small 2U chassis
providing the ultimate in ease of installation.''',
                        style=ParagraphStyle(
                                name="base",
                                fontName="Helvetica",
                                leading=12,
                                leftIndent=0,
                                firstLineIndent=0,
                                spaceBefore = 9.5,
                                fontSize=9.5,
                                )
                            ),
                    imageSide='left',
                    )
                )

        story.append(PageBreak())
        story.append(Paragraph('Image larger than the frame',h3))
        story.append(ImageAndFlowables(
                        Image(gif,width=6*110,height=6*44),
                        Paragraph('''The concept of an integrated one box solution for advanced voice and
data applications began with the introduction of the IMACS. The
IMACS 200 carries on that tradition with an integrated solution
optimized for smaller port size applications that the IMACS could not
economically address. An array of the most popular interfaces and
features from the IMACS has been bundled into a small 2U chassis
providing the ultimate in ease of installation.''',
                        style=ParagraphStyle(
                                name="base",
                                fontName="Helvetica",
                                leading=12,
                                leftIndent=0,
                                firstLineIndent=0,
                                spaceBefore = 9.5,
                                fontSize=9.5,
                                )
                            ),
                    imageSide='left',
                    )
                )

        
        doc = MyDocTemplate(outputfile('test_platypus_imageandflowables.pdf'),showBoundary=1)
        doc.multiBuild(story)
Ejemplo n.º 41
0
def old_tables_test():
    from reportlab.lib.units import inch, cm
    from reportlab.platypus.flowables import Image, PageBreak, Spacer, XBox
    from reportlab.platypus.paragraph import Paragraph
    from reportlab.platypus.xpreformatted import XPreformatted
    from reportlab.platypus.flowables import Preformatted
    from reportlab.platypus.doctemplate import SimpleDocTemplate
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.platypus.tables import GRID_STYLE, BOX_STYLE, LABELED_GRID_STYLE, COLORED_GRID_STYLE, LIST_STYLE, LongTable
    rowheights = (24, 16, 16, 16, 16)
    rowheights2 = (24, 16, 16, 16, 30)
    colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
    data = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    data2 = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats\nLarge', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    lst = []
    lst.append(Paragraph("Tables", styleSheet['Heading1']))
    lst.append(Paragraph(__doc__, styleSheet['BodyText']))
    lst.append(Paragraph("The Tables (shown in different styles below) were created using the following code:", styleSheet['BodyText']))
    lst.append(Preformatted("""
    colwidths = (50, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32)
    rowheights = (24, 16, 16, 16, 16)
    data = (
        ('', 'Jan', 'Feb', 'Mar','Apr','May', 'Jun',
           'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159,
             888, '1,298', 832, 453, '1,344','2,843')
        )
    t = Table(data, colwidths, rowheights)
    """, styleSheet['Code'], dedent=4))
    lst.append(Paragraph("""
    You can then give the Table a TableStyle object to control its format. The first TableStyle used was
    created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
GRID_STYLE = TableStyle(
    [('GRID', (0,0), (-1,-1), 0.25, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))
    lst.append(Paragraph("""
    TableStyles are created by passing in a list of commands. There are two types of commands - line commands
    and cell formatting commands. In all cases, the first three elements of a command are the command name,
    the starting cell and the ending cell.
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    Line commands always follow this with the weight and color of the desired lines. Colors can be names,
    or they can be specified as a (R,G,B) tuple, where R, G and B are floats and (0,0,0) is black. The line
    command names are: GRID, BOX, OUTLINE, INNERGRID, LINEBELOW, LINEABOVE, LINEBEFORE
    and LINEAFTER. BOX and OUTLINE are equivalent, and GRID is the equivalent of applying both BOX and
    INNERGRID.
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    Cell formatting commands are:
    """, styleSheet['BodyText']))
    lst.append(Paragraph("""
    FONT - takes fontname, fontsize and (optional) leading.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    TEXTCOLOR - takes a color name or (R,G,B) tuple.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    ALIGNMENT (or ALIGN) - takes one of LEFT, RIGHT, CENTRE (or CENTER) or DECIMAL.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    LEFTPADDING - defaults to 6.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    RIGHTPADDING - defaults to 6.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    BOTTOMPADDING - defaults to 3.
    """, styleSheet['Definition']))
    lst.append(Paragraph("""
    A tablestyle is applied to a table by calling Table.setStyle(tablestyle).
    """, styleSheet['BodyText']))
    t = Table(data, colwidths, rowheights)
    t.setStyle(GRID_STYLE)
    lst.append(PageBreak())
    lst.append(Paragraph("This is GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)

    t = Table(data, colwidths, rowheights)
    t.setStyle(BOX_STYLE)
    lst.append(Paragraph("This is BOX_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
BOX_STYLE = TableStyle(
    [('BOX', (0,0), (-1,-1), 0.50, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    t.setStyle(LABELED_GRID_STYLE)
    lst.append(Paragraph("This is LABELED_GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    t = Table(data2, colwidths, rowheights2)
    t.setStyle(LABELED_GRID_STYLE)
    lst.append(Paragraph("This is LABELED_GRID_STYLE ILLUSTRATES EXPLICIT LINE SPLITTING WITH NEWLINE (different heights and data)\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
LABELED_GRID_STYLE = TableStyle(
    [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
     ('BOX', (0,0), (-1,-1), 2, colors.black),
     ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
     ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))
    lst.append(PageBreak())

    t = Table(data, colwidths, rowheights)
    t.setStyle(COLORED_GRID_STYLE)
    lst.append(Paragraph("This is COLORED_GRID_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
COLORED_GRID_STYLE = TableStyle(
    [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
     ('BOX', (0,0), (-1,-1), 2, colors.red),
     ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
     ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    t.setStyle(LIST_STYLE)
    lst.append(Paragraph("This is LIST_STYLE\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
LIST_STYLE = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
    )
    """, styleSheet['Code']))

    t = Table(data, colwidths, rowheights)
    ts = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 3, colors.green,'butt'),
     ('LINEBELOW', (0,-1), (-1,-1), 1, colors.white,'butt'),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
     ('TEXTCOLOR', (0,1), (0,-1), colors.red),
     ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
    )
    t.setStyle(ts)
    lst.append(Paragraph("This is a custom style\n", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Paragraph("""
    It was created as follows:
    """, styleSheet['BodyText']))
    lst.append(Preformatted("""
   ts = TableStyle(
    [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
     ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
     ('LINEBELOW', (0,-1), (-1,-1), 3, colors.green,'butt'),
     ('LINEBELOW', (0,-1), (-1,-1), 1, colors.white,'butt'),
     ('ALIGN', (1,1), (-1,-1), 'RIGHT'),
     ('TEXTCOLOR', (0,1), (0,-1), colors.red),
     ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))]
    )
    """, styleSheet['Code']))
    data = (
        ('', 'Jan\nCold', 'Feb\n', 'Mar\n','Apr\n','May\n', 'Jun\nHot', 'Jul\n', 'Aug\nThunder', 'Sep\n', 'Oct\n', 'Nov\n', 'Dec\n'),
        ('Mugs', 0, 4, 17, 3, 21, 47, 12, 33, 2, -2, 44, 89),
        ('T-Shirts', 0, 42, 9, -3, 16, 4, 72, 89, 3, 19, 32, 119),
        ('Key Ring', 0,0,0,0,0,0,1,0,0,0,2,13),
        ('Hats', 893, 912, '1,212', 643, 789, 159, 888, '1,298', 832, 453, '1,344','2,843')
        )
    c = list(colwidths)
    c[0] = None
    c[8] = None
    t = Table(data, c, [None]+list(rowheights[1:]))
    t.setStyle(LIST_STYLE)
    lst.append(Paragraph("""
        This is a LIST_STYLE table with the first rowheight set to None ie automatic.
        The top row cells are split at a newline '\\n' character. The first and August
        column widths were also set to None.
    """, styleSheet['BodyText']))
    lst.append(t)

    lst.append(Paragraph("""
        This demonstrates a number of features useful in financial statements. The first is decimal alignment;
        with ALIGN=DECIMAL the numbers align on the points; and the points are aligned based on
        the RIGHTPADDING, which is usually 3 points so you should set it higher.  The second is multiple lines;
        one can specify double or triple lines and control the separation if desired. Finally, the coloured
        negative numbers were (we regret to say) done in the style; we don't have a way to conditionally
        format numbers based on value yet.
    """, styleSheet['BodyText']))


    t = Table([['Corporate Assets','Amount'],
               ['Fixed Assets','1,234,567.89'],
               ['Company Vehicle','1,234.8901'],
               ['Petty Cash','42'],
               [u'Intellectual Property\u00ae','(42,078,231.56)'],
               ['Overdraft','(12,345)'],
               ['Boardroom Flat Screen','60 inches'],
               ['Net Position','Deep Sh*t.Really']
               ],
              [144,72])

    ts = TableStyle(
        [#first the top row
         ('ALIGN', (1,1), (-1,-1), 'CENTER'),
         ('LINEABOVE', (0,0), (-1,0), 1, colors.purple),
         ('LINEBELOW', (0,0), (-1,0), 1, colors.purple),
         ('FONT', (0,0), (-1,0), 'Times-Bold'),

        #bottom row has a line above, and two lines below
         ('LINEABOVE', (0,-1), (-1,-1), 1, colors.purple),  #last 2 are count, sep
         ('LINEBELOW', (0,-1), (-1,-1), 0.5, colors.purple, 1, None, None, 4,1),
         ('LINEBELOW', (0,-1), (-1,-1), 1, colors.red),
         ('FONT', (0,-1), (-1,-1), 'Times-Bold'),

        #numbers column
         ('ALIGN', (1,1), (-1,-1), 'DECIMAL'),
         ('RIGHTPADDING', (1,1), (-1,-1), 36),
         ('TEXTCOLOR', (1,4), (1,4), colors.red),

        #red cell
        ]
        )

    t.setStyle(ts)
    lst.append(t)
    lst.append(Spacer(36,36))
    lst.append(Paragraph("""
        The red numbers should be aligned LEFT &amp; BOTTOM, the blue RIGHT &amp; TOP
        and the green CENTER &amp; MIDDLE.
    """, styleSheet['BodyText']))
    XY  =   [['X00y', 'X01y', 'X02y', 'X03y', 'X04y'],
            ['X10y', 'X11y', 'X12y', 'X13y', 'X14y'],
            ['X20y', 'X21y', 'X22y', 'X23y', 'X24y'],
            ['X30y', 'X31y', 'X32y', 'X33y', 'X34y']]
    t=Table(XY, 5*[0.6*inch], 4*[0.6*inch])
    t.setStyle([('ALIGN',(1,1),(-2,-2),'LEFT'),
                ('TEXTCOLOR',(1,1),(-2,-2),colors.red),

                ('VALIGN',(0,0),(1,-1),'TOP'),
                ('ALIGN',(0,0),(1,-1),'RIGHT'),
                ('TEXTCOLOR',(0,0),(1,-1),colors.blue),

                ('ALIGN',(0,-1),(-1,-1),'CENTER'),
                ('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
                ('TEXTCOLOR',(0,-1),(-1,-1),colors.green),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                ])
    lst.append(t)
    data = [('alignment', 'align\012alignment'),
            ('bulletColor', 'bulletcolor\012bcolor'),
            ('bulletFontName', 'bfont\012bulletfontname'),
            ('bulletFontSize', 'bfontsize\012bulletfontsize'),
            ('bulletIndent', 'bindent\012bulletindent'),
            ('firstLineIndent', 'findent\012firstlineindent'),
            ('fontName', 'face\012fontname\012font'),
            ('fontSize', 'size\012fontsize'),
            ('leading', 'leading'),
            ('leftIndent', 'leftindent\012lindent'),
            ('rightIndent', 'rightindent\012rindent'),
            ('spaceAfter', 'spaceafter\012spacea'),
            ('spaceBefore', 'spacebefore\012spaceb'),
            ('textColor', 'fg\012textcolor\012color')]
    t = Table(data)
    t.setStyle([
            ('VALIGN',(0,0),(-1,-1),'TOP'),
            ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
            ('BOX', (0,0), (-1,-1), 0.25, colors.black),
            ])
    lst.append(t)
    t = Table([ ('Attribute', 'Synonyms'),
                ('alignment', 'align, alignment'),
                ('bulletColor', 'bulletcolor, bcolor'),
                ('bulletFontName', 'bfont, bulletfontname'),
                ('bulletFontSize', 'bfontsize, bulletfontsize'),
                ('bulletIndent', 'bindent, bulletindent'),
                ('firstLineIndent', 'findent, firstlineindent'),
                ('fontName', 'face, fontname, font'),
                ('fontSize', 'size, fontsize'),
                ('leading', 'leading'),
                ('leftIndent', 'leftindent, lindent'),
                ('rightIndent', 'rightindent, rindent'),
                ('spaceAfter', 'spaceafter, spacea'),
                ('spaceBefore', 'spacebefore, spaceb'),
                ('textColor', 'fg, textcolor, color')])
    t.repeatRows = 1
    t.setStyle([
                ('FONT',(0,0),(-1,1),'Times-Bold',10,12),
                ('FONT',(0,1),(-1,-1),'Courier',8,8),
                ('VALIGN',(0,0),(-1,-1),'MIDDLE'),
                ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
                ('BOX', (0,0), (-1,-1), 0.25, colors.black),
                ('BACKGROUND', (0, 0), (-1, 0), colors.green),
                ('BACKGROUND', (0, 1), (-1, -1), colors.pink),
                ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
                ('ALIGN', (0, 1), (0, -1), 'LEFT'),
                ('ALIGN', (-1, 1), (-1, -1), 'RIGHT'),
                ('FONT', (0, 0), (-1, 0), 'Times-Bold', 12),
                ('ALIGN', (1, 1), (1, -1), 'CENTER'),
                ])
    lst.append(t)
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 5,6),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.blue),]))
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 10,12),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.black),]))
    lst.append(Table(XY,
            style=[ ('FONT',(0,0),(-1,-1),'Times-Roman', 20,24),
                    ('GRID', (0,0), (-1,-1), 0.25, colors.red),]))
    lst.append(PageBreak())
    data=  [['00', '01', '02', '03', '04'],
            ['10', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34']]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('TEXTCOLOR',(0,-1),(-2,-1),colors.green),
                    ])
    lst.append(Paragraph("Illustrating splits: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,30)", styleSheet['BodyText']))
    for s in t.split(4*inch,30):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,36)", styleSheet['BodyText']))
    for s in t.split(4*inch,36):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    lst.append(Paragraph("Illustrating splits: repeated split(4in,30)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    S = t.split(4*inch,30)
    s = S.pop(-1)
    S.extend(s.split(4*inch,30))
    s = S.pop(-1)
    S.extend(s.split(4*inch,30))

    for s in S:
        lst.append(s)
        lst.append(Spacer(0,6))

    lst.append(PageBreak())
    data=  [['00', '01', '02', '03', '04'],
            ['', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '', '33', '34']]
    sty=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('SPAN',(0,0),(0,1)),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('SPAN',(2,2),(2,3)),
                    ]
    t=Table(data,style=sty)
    lst.append(Paragraph("Illustrating splits with spans: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,30)", styleSheet['BodyText']))
    for s in t.split(4*inch,30):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,36)", styleSheet['BodyText']))
    for s in t.split(4*inch,36):
        lst.append(s)
        lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    data=  [['00', '01', '02', '03', '04'],
            ['', '11', '12', '13', ''],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '', '33', ''],
            ['40', '41', '', '43', '44']]
    sty=[
        ('GRID',(0,0),(-1,-1),0.5,colors.grey),
        ('GRID',(1,1),(-2,-2),1,colors.green),
        ('BOX',(0,0),(1,-1),2,colors.red),
        ('BOX',(0,0),(-1,-1),2,colors.black),
        ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
        ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
        ('BACKGROUND', (0, 0), (0, 1), colors.pink),
        ('SPAN',(0,0),(0,1)),
        ('BACKGROUND',(-2,1),(-1,1),colors.palegreen),
        ('SPAN',(-2,1),(-1,1)),
        ('BACKGROUND',(-2,3),(-1,3),colors.yellow),
        ('SPAN',(-2,3),(-1,3)),
        ('BACKGROUND', (2, 3), (2, 4), colors.orange),
        ('SPAN',(2,3),(2,4)),
        ]

    t=Table(data,style=sty,repeatRows=2)
    lst.append(Paragraph("Illustrating splits with spans and repeatRows: nosplit", styleSheet['BodyText']))
    lst.append(t)
    lst.append(Spacer(0,6))
    if  1:
        lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,30)", styleSheet['BodyText']))
        for s in t.split(4*inch,30):
            lst.append(s)
            lst.append(Spacer(0,6))
        lst.append(Spacer(0,6))
        lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,36)", styleSheet['BodyText']))
        for s in t.split(4*inch,36):
            lst.append(s)
            lst.append(Spacer(0,6))
    lst.append(Paragraph("Illustrating splits with spans and repeatRows: split(4in,56)", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    for s in t.split(4*inch,56):
        lst.append(s)
        lst.append(Spacer(0,6))

    lst.append(PageBreak())
    from reportlab.lib.testutils import testsFolder
    I = Image(os.path.join(os.path.dirname(testsFolder),'tools','pythonpoint','demos','leftlogo.gif'))
    I.drawHeight = 1.25*inch*I.drawHeight / I.drawWidth
    I.drawWidth = 1.25*inch
    #I.drawWidth = 9.25*inch #uncomment to see better messaging
    P = Paragraph("<para align=center spaceb=3>The <b>ReportLab Left <font color=red>Logo</font></b> Image</para>", styleSheet["BodyText"])
    B = TableBarChart()
    BP = Paragraph("<para align=center spaceb=3>A bar chart in a cell.</para>", styleSheet["BodyText"])

    data=  [['A', 'B', 'C', Paragraph("<b>A pa<font color=red>r</font>a<i>graph</i></b><super><font color=yellow>1</font></super>",styleSheet["BodyText"]), 'D'],
            ['00', '01', '02', [I,P], '04'],
            ['10', '11', '12', [I,P], '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34'],
            ['40', '41', '42', [B,BP], '44']]

    t=Table(data,style=[('GRID',(1,1),(-2,-2),1,colors.green),
                    ('BOX',(0,0),(1,-1),2,colors.red),
                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('BOX',(0,0),(-1,-1),2,colors.black),
                    ('GRID',(0,0),(-1,-1),0.5,colors.black),
                    ('VALIGN',(3,0),(3,0),'BOTTOM'),
                    ('BACKGROUND',(3,0),(3,0),colors.limegreen),
                    ('BACKGROUND',(3,1),(3,1),colors.khaki),
                    ('ALIGN',(3,1),(3,1),'CENTER'),
                    ('BACKGROUND',(3,2),(3,2),colors.beige),
                    ('ALIGN',(3,2),(3,2),'LEFT'),
                    ])

    t._argW[3]=1.5*inch
    lst.append(t)

    # now for an attempt at column spanning.
    lst.append(PageBreak())
    data=  [['A', 'BBBBB', 'C', 'D', 'E'],
            ['00', '01', '02', '03', '04'],
            ['10', '11', '12', '13', '14'],
            ['20', '21', '22', '23', '24'],
            ['30', '31', '32', '33', '34']]
    sty = [
            ('ALIGN',(0,0),(-1,-1),'CENTER'),
            ('VALIGN',(0,0),(-1,-1),'TOP'),
            ('GRID',(0,0),(-1,-1),1,colors.green),
            ('BOX',(0,0),(-1,-1),2,colors.red),

            #span 'BBBB' across middle 3 cells in top row
            ('SPAN',(1,0),(3,0)),
            #now color the first cell in this range only,
            #i.e. the one we want to have spanned.  Hopefuly
            #the range of 3 will come out khaki.
            ('BACKGROUND',(1,0),(1,0),colors.khaki),

            ('SPAN',(0,2),(-1,2)),


            #span 'AAA'down entire left column
            ('SPAN',(0,0), (0, 1)),
            ('BACKGROUND',(0,0),(0,0),colors.cyan),
            ('TEXTCOLOR', (0,'splitfirst'), (-1,'splitfirst'), colors.cyan),
            ('TEXTCOLOR', (0,'splitlast'), (-1,'splitlast'), colors.red),
            ('BACKGROUND', (0,'splitlast'), (-1,'splitlast'), colors.pink),
            ('LINEBELOW', (0,'splitlast'), (-1,'splitlast'), 1, colors.grey,'butt'),
           ]
    t=Table(data,style=sty, colWidths = [20] * 5, rowHeights = [20]*5)
    lst.append(t)
    lst.append(Spacer(18,18))

    t=Table(data,style=sty, colWidths = [20] * 5, rowHeights = [20]*5)
    for s in t.split(4*inch,72):
        lst.append(s)
        lst.append(Spacer(0,6))

    # now for an attempt at percentage widths
    lst.append(Spacer(18,18))
    lst.append(Paragraph("This table has colWidths=5*['14%']!", styleSheet['BodyText']))
    t=Table(data,style=sty, colWidths = ['14%'] * 5, rowHeights = [20]*5)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph("This table has colWidths=['14%','10%','19%','22%','*']!", styleSheet['BodyText']))
    t=Table(data,style=sty, colWidths = ['14%','10%','19%','22%','*'], rowHeights = [20]*5)
    lst.append(t)

    # Mike's test example
    lst.append(Spacer(18,18))
    lst.append(Paragraph('Mike\'s Spanning Example', styleSheet['Heading1']))
    data=  [[Paragraph('World Domination: The First Five Years', styleSheet['BodyText']), ''],
            [Paragraph('World <font color="green">Domination</font>: The First Five Years', styleSheet['BodyText']),''],
            [Paragraph('World Domination: The First Five Years', styleSheet['BodyText']), ''],
            ]
    t=Table(data, style=[('SPAN',(0,0),(1,0)),('SPAN',(0,1),(1,1)),('SPAN',(0,2),(1,2)),], colWidths = [3*cm,8*cm], rowHeights = [None]*3)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph('Mike\'s Non-spanning Example', styleSheet['Heading1']))
    data=  [[Paragraph('World Domination: The First Five Years', styleSheet['BodyText'])],
            [Paragraph('World <font color="magenta">Domination</font>: The First Five Years', styleSheet['BodyText'])],
            [Paragraph('World Domination: The First Five Years', styleSheet['BodyText'])],
            ]
    t=Table(data, style=[], colWidths = [11*cm], rowHeights = [None]*3)
    lst.append(t)

    lst.append(Spacer(18,18))
    lst.append(Paragraph('xpre example', styleSheet['Heading1']))
    data=  [    [
                XPreformatted('Account Details', styleSheet['Heading3']),
                '', XPreformatted('Client Details', styleSheet['Heading3']),
                ],  #end of row 0
            ]
    t=Table(data, style=[], colWidths = [80,230.0,80], rowHeights = [None]*1)
    lst.append(t)

    lst.append(PageBreak())

    lst.append(Paragraph('Trying colour cycling in background', styleSheet['Heading1']))
    lst.append(Paragraph("This should alternate pale blue and uncolored by row", styleSheet['BodyText']))
    data=  [['001', '01', '02', '03', '04', '05'],
            ['002', '01', '02', '03', '04', '05'],
            ['003', '01', '02', '03', '04', '05'],
            ['004', '01', '02', '03', '04', '05'],
            ['005', '01', '02', '03', '04', '05'],
            ['006', '01', '02', '03', '04', '05'],
            ['007', '01', '02', '03', '04', '05'],
            ['008', '01', '02', '03', '04', '05'],
            ['009', '01', '02', '03', '04', '05'],
            ['010', '01', '02', '03', '04', '05'],

            ]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('ROWBACKGROUNDS', (0, 0), (-1, -1), (0xD0D0FF, None)),
                    ])
    lst.append(t)
    lst.append(Spacer(0,6))
    lst.append(Paragraph("And this should pale blue, pale pink and None by column", styleSheet['BodyText']))
    data=  [['001', '01', '02', '03', '04', '05'],
            ['002', '01', '02', '03', '04', '05'],
            ['003', '01', '02', '03', '04', '05'],
            ['004', '01', '02', '03', '04', '05'],
            ['005', '01', '02', '03', '04', '05'],
            ['006', '01', '02', '03', '04', '05'],
            ['007', '01', '02', '03', '04', '05'],
            ['008', '01', '02', '03', '04', '05'],
            ['009', '01', '02', '03', '04', '05'],
            ['010', '01', '02', '03', '04', '05'],

            ]
    t=Table(data,style=[
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('COLBACKGROUNDS', (0, 0), (-1, -1), (0xD0D0FF, 0xFFD0D0, None)),
                    ])
    lst.append(t)

    lst.append(PageBreak())
    lst.append(Paragraph("This spanning example illustrates automatic removal of grids and lines in spanned cells!", styleSheet['BodyText']))
    lst.append(Spacer(0,6))
    data=  [['Top\nLeft', '', '02', '03', '04', '05', '06', '07'],
            ['', '', '12', 'Span (3,1) (6,2)', '','','','17'],
            ['20', '21', '22', '', '','','','27'],
            ['30', '31', '32', '33', '34','35','36','37'],
            ['40', 'In The\nMiddle', '', '', '44','45','46','47'],
            ['50', '', '', '', '54','55','56','57'],
            ['60', '', '', '','64', '65', 'Bottom\nRight', ''],
            ['70', '71', '72', '73','74', '75', '', '']]
    t=Table(data,style=[
            ('GRID',(0,0),(-1,-1),0.5,colors.grey),
            ('BACKGROUND',(0,0),(1,1),colors.palegreen),
            ('SPAN',(0,0),(1,1)),
            ('BACKGROUND',(-2,-2),(-1,-1), colors.pink),
            ('SPAN',(-2,-2),(-1,-1)),
            ('SPAN',(1,4),(3,6)),
            ('BACKGROUND',(1,4),(3,6), colors.lightblue),
            ('SPAN',(3,1),(6,2)),
            ('BACKGROUND',(3,1),(6,2), colors.peachpuff),
            ('VALIGN',(3,1),(6,2),'TOP'),
            ('LINEABOVE', (0,2),(-1,2), 1, colors.black, 0, None, None, 2, 2),
            ('LINEBEFORE', (3,0),(3,-1), 1, colors.black, 0, None, None, 2, 2),
            ])
    lst.append(t)

    lst.append(PageBreak())

    lst.append(Paragraph("und jetzt noch eine Tabelle mit 5000 Zeilen:", styleSheet['BodyText']))
    sty = [ ('GRID',(0,0),(-1,-1),1,colors.green),
            ('BOX',(0,0),(-1,-1),2,colors.red),
           ]
    data = [[str(i), Paragraph("xx "* (i%10), styleSheet["BodyText"]), Paragraph("blah "*(i%40), styleSheet["BodyText"])] for i in range(500)]
    t=LongTable(data, style=sty, colWidths = [50,100,200])
    lst.append(t)

    #Yuan Hong's bug tester
    lst.append(PageBreak())
    lst.append(Paragraph('Yian Hong\'s Bug Case (should not blow up)', styleSheet['Heading2']))
    data = ([['Col1', 'Col2', 'Col3', 'Col4', 'Col5']]+
                [['01', Paragraph('This is cell one that contains a paragraph.', styleSheet['Normal']), '02', '03', '04']
                    for i in range(50)])

    t = Table(data, ['20%']*5, repeatRows=1)
    t.setStyle(TableStyle([
        ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
        ('BOX', (0,0), (-1,-1), 0.25, colors.black),
        ('SPAN', (0,50), (-2,50)),
        ]))

    lst.append(t)
    lst.append(PageBreak())

    #Volker Haas' example extended
    #the optimal row heights are the solution of an LP similar to
    #
    #Objective function
    #   min: 3*h0+3*h1+3*h2+2*h3;
    #
    #constraints
    #   h0>=12;
    #   h1>=12;
    #   h2>=12;
    #   h3>=12;
    #   h0+h1+h2>=48;
    #   h0+h1>=12;
    #   h2+h3>=60;
    #
    #the solution H=[12,12,24,36]
    def makeTable(x,y):
        return Table([
                ['00', '01', '02', '03', '04', '05\nline2\nline3\nline4'],
                ['', '11', '12', x, '',''],
                ['20', '21', y, '23', '24',''],
                ['30', '31', '', '33', '34','35'],
                ],
                style=[
                    ('TOPPADDING',(0,0),(-1,-1),0),
                    ('BOTTOMPADDING',(0,0),(-1,-1),0),
                    ('RIGHTPADDING',(0,0),(-1,-1),0),
                    ('LEFTPADDING',(0,0),(-1,-1),0),
                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
                    ('SPAN',(0,0),(0,1)),
                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                    ('SPAN',(2,2),(2,3)),
                    ('SPAN',(3,1),(4,1)),
                    ('SPAN',(5,0),(5,2)),
                ])
    p_style= ParagraphStyle('Normal')
    lst.append(makeTable(
            Paragraph('This is a string',p_style),
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))

    lst.append(Spacer(10,10))
    lst.append(makeTable(
            XPreformatted('This is a string',p_style),
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))
    lst.append(Spacer(10,10))
    lst.append(makeTable(
            'This is a string',
            '22\nblub\nasfd\nafd\nasdfs',
            ))
    lst.append(Spacer(10,10))
    lst.append(makeTable(
            'This is a string',
            Paragraph('22<br/>blub<br/>asfd<br/>afd<br/>asdfs', p_style)
            ))
    SimpleDocTemplate(outputfile('test_platypus_tables_2.pdf'), showBoundary=1).build(lst)
Ejemplo n.º 42
0
 def render_page2_image(self):
     #TODO добыть картинку 2 стороны
     A4_Width, A4_Height = A4
     self.im = Image(_self_path + '/'+u'side2.jpg',width=A4_Height, height=A4_Width)
     self.im.drawOn(self.pdf, self.x(0), self.y(0))
     self.pdf.line(A4_Height/2, 10, A4_Height/2, A4_Width-10)
 def render_page1_image(self):
     A4_Width, A4_Height = A4
     self.im = Image(_self_path + "/" + u"post1.JPG", width=A4_Height, height=A4_Width)
     self.im.drawOn(self.pdf, self.x(0), self.y(0))
Ejemplo n.º 44
0
 def add_image(self, src, width, height, align=CENTER):
     img = Image(src, width, height)
     img.hAlign = align
     self.add(img)
Ejemplo n.º 45
0
 def render_page1_image(self):
     A4_Width, A4_Height = A4
     self.im = Image(_self_path + '/'+u'side1.jpg',width=A4_Height, height=A4_Width)
     self.im.drawOn(self.pdf, self.x(0), self.y(0))
     self.pdf.line(A4_Height/2, 10, A4_Height/2, A4_Width-10)
Ejemplo n.º 46
0
 def wrap(self,availWidth,availHeight):
     h, w = Image.wrap(self,availHeight,availWidth)
     return w, h
Ejemplo n.º 47
0
def pdf(group, bill):
    """PDF version of bill"""

    width, height = A4
    margin = 1 * cm
    heading = 2 * cm

    logo_height = 1.5 * cm

    font_name = 'Times-Roman'
    font_size = 16

    filename = '%s-%s-%s-%s' % (date.today(), group, _('bill'), bill.id)

    response = HttpResponse(mimetype='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=%s.pdf' % (
        slugify(filename))

    show_logo = bool(group.logo and group.logo.storage.exists(group.logo.path))

    if show_logo:
        ratio = group.logo.width / group.logo.height
        logo = Image(group.logo.path,
                     width=logo_height * ratio,
                     height=logo_height)

    def draw_header(canvas, doc):
        if show_logo:
            logo.drawOn(canvas, width / 2 - 1 * margin - logo_height * ratio,
                        height - margin - logo_height)

        canvas.setFont(font_name, font_size)
        canvas.drawString(margin, height - margin - font_size,
                          _('Bill #%d') % (bill.id))
        canvas.setFont(font_name, font_size - 4)
        canvas.drawString(
            margin, height - margin - 2 * font_size,
            bill.created.strftime(_('%Y-%m-%d %H:%M').encode('utf-8')))

    frames = [
        Frame(0,
              0,
              width / 2,
              height - heading,
              leftPadding=margin,
              bottomPadding=margin,
              rightPadding=margin / 2,
              topPadding=margin),
        Frame(width / 2,
              0,
              width / 2,
              height,
              leftPadding=margin / 2,
              bottomPadding=margin,
              rightPadding=margin,
              topPadding=margin),
    ]

    templates = [PageTemplate(frames=frames, onPage=draw_header)]

    doc = BaseDocTemplate(response, pagesize=(width, height))
    doc.addPageTemplates(templates)

    data = [[_('Description'), _('Amount')]]
    total = 0

    for line in bill.billingline_set.all():
        data.append([line.description, '%.2f' % line.amount])
        total += line.amount

    data.append(['', '%.2f' % total])

    table = Table(data, colWidths=[doc.width * 0.4, doc.width * 0.15])
    table.setStyle(table_style)
    table.hAlign = 'LEFT'

    parts = []
    for line in bill.description.split('\n'):
        parts.append(Paragraph(escape(line), styles['Normal']))
    parts.append(Spacer(0.2 * cm, 0.2 * cm))
    parts.append(KeepTogether(table))

    doc.build(parts)

    return response
Ejemplo n.º 48
0
 def insertImage(self, imagePath, height, width):
     img = Image(imagePath)
     img.drawHeight = height
     img.drawWidth = width
     self.Story.append(img)
Ejemplo n.º 49
0
class F116Pdf(f116_pdf_old.F116PdfOld):
    def __init__(self, data, debug=False):
        super(F116Pdf, self).__init__(data, debug)

    def create_pdf_file(self, file_name, page_size=landscape(A4)):
        super(F116Pdf, self).create_pdf_file(file_name, page_size)
    
    def render_page1_image(self):
        A4_Width, A4_Height = A4
        self.im = Image(_self_path + '/'+u'side1.jpg',width=A4_Height, height=A4_Width)
        self.im.drawOn(self.pdf, self.x(0), self.y(0))
        self.pdf.line(A4_Height/2, 10, A4_Height/2, A4_Width-10)

    def render_page2_image(self):
        #TODO добыть картинку 2 стороны
        A4_Width, A4_Height = A4
        self.im = Image(_self_path + '/'+u'side2.jpg',width=A4_Height, height=A4_Width)
        self.im.drawOn(self.pdf, self.x(0), self.y(0))
        self.pdf.line(A4_Height/2, 10, A4_Height/2, A4_Width-10)

    def render_page1_oneside_data(self, side_data):
        self.pdf.setFont('DejaVuSans', 8)

        #money
        self.pdf.setFont('DejaVuSans', 12)
        self.pdf.drawString(self.x(0.9*cm), self.y(15.85*cm), side_data.sum + u" руб. 00 коп.")
        self.pdf.setFont('DejaVuSans', 10)
        self.pdf.drawString(self.x(2.20*cm), self.y(3.92*cm), side_data.sum)
        
        #to
        self.pdf.setFont('DejaVuSans', 8)
        #name
        self.drawClippingString2(side_data.to_name, self.x(1.7*cm), self.y(14.4*cm), 47)
        #address - if need split
        if len(side_data.to_address) >= 50: # 33chars for font size 8
            #split to 2 line
            self.drawClippingString2(side_data.to_address[:50], self.x(1.79*cm), self.y(13.85*cm), 50)
            #if len(side_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString2(side_data.to_address[50:], self.x(0.9*cm), self.y(13.2*cm), 55)
        else:
            self.drawClippingString2(side_data.to_address, self.x(1.79*cm), self.y(13.85*cm), 50)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(6.86*cm), self.y(12.55*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(8)
        zip_code.textLine(side_data.to_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)
        
        #from
        #name
        self.drawClippingString2(side_data.from_name, self.x(2.0*cm), self.y(11.85*cm), 68)
        #address - if need split
        if len(side_data.from_address) >= 72: # chars for font size 8
            #split to 2 line
            self.drawClippingString2(side_data.from_address[:72], self.x(1.8*cm), self.y(11.12*cm), 72)
            #if len(side_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString2(side_data.from_address[72:], self.x(0.9*cm), self.y(10.55*cm), 57)
        else:
            self.drawClippingString2(side_data.from_address, self.x(1.8*cm), self.y(11.12*cm), 72)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(10.45*cm), self.y(10.6*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(7.5)
        zip_code.textLine(side_data.from_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)


        #to_down
        self.pdf.setFont('DejaVuSans', 8)
        #name
        self.drawClippingString2(side_data.to_name, self.x(1.7*cm), self.y(3.12*cm), 73)
        #address - if need split
        if len(side_data.to_address) >= 60: # 60chars for font size 8
            #split to 2 line
            self.drawClippingString2(side_data.to_address[:60], self.x(1.8*cm), self.y(2.35*cm), 70)
            #if len(self.lside_data.to_address[34:] >= ?)# need 3 line?
            self.drawClippingString2(side_data.to_address[60:], self.x(0.9*cm), self.y(1.55*cm), 57)
        else:
            self.drawClippingString2(side_data.to_address, self.x(1.8*cm), self.y(2.35*cm), 77)
            
        #zip_code
        zip_code = self.pdf.beginText()
        zip_code.setTextOrigin(self.x(10.4*cm), self.y(1.6*cm))
        zip_code.setFont('DejaVuSans', 10)
        zip_code.setCharSpace(8)
        zip_code.textLine(side_data.to_zip_code)
        zip_code.setCharSpace(0)
        self.pdf.drawText(zip_code)
        
        #passport data
        self.pdf.setFontSize(8)
        self.drawClippingString2(side_data.passport_type , self.x(2.9*cm), self.y(9.18*cm), 8)
        self.drawClippingString2(side_data.passport_series , self.x(5.85*cm), self.y(9.18*cm), 4)
        self.drawClippingString2(side_data.passport_number , self.x(7.6*cm), self.y(9.18*cm), 6)
        self.drawClippingString2(side_data.passport_dt1 , self.x(10.5*cm), self.y(9.18*cm), 5)
        self.drawClippingString2(side_data.passport_dt2 , self.x(12.5*cm), self.y(9.18*cm), 2)
        self.drawClippingString2(side_data.passport_by , self.x(0.8*cm), self.y(8.6*cm), 75)
        
     

    def _make_page1_pdf_file(self, file_name=u'page1.pdf'):
        self.create_pdf_file(file_name, page_size=landscape(A4))
        self.set_cyrillic_font()
        self.render_page1_image()
        self.render_page1_oneside_data(self.lside_data)
        self.base_x += 15.1*cm
        #self.base_y += -0.14*cm
        self.render_page1_oneside_data(self.rside_data)
        self.pdf.showPage() # page end
        #page 2
        self.base_x = 0
        self.base_y = 0
        self.render_page2_image()
        self.end_page()
        self.write_pdf_file()
    
    def make_pdf_file(self, file_name=u'F116.pdf'):
        self._make_page1_pdf_file(file_name)
 def add_image(self, src, width, height, align=CENTER):
     img = Image(src, width, height)
     img.hAlign = align
     self.add(img)
Ejemplo n.º 51
0
 def draw(self):
     self.canv.rotate(90)
     Image.draw(self)
Ejemplo n.º 52
0
    def Dessine_texte(self, texte="", nom_categorie=None, y=0, hauteur=0):
        """ Dessine le texte de la case """
        if texte == None :
            texte = ""

        # Dessine le nom de la catégorie
        if nom_categorie != None :
            self.canvas.saveState()
            self.canvas.setStrokeColor(ColorWxToPdf(self.parent.dictDonnees["case_titre_texte_couleur"], alpha=1))
            self.canvas.setFillColor(ColorWxToPdf(self.parent.dictDonnees["case_titre_texte_couleur"], alpha=1))
            self.canvas.setLineWidth(0.5)
            self.canvas.setDash(0.5, 4)
            self.canvas.line(0, self.hauteur_case - y +1, self.largeur_case, self.hauteur_case - y +1)

            self.canvas.setFont(self.parent.dictDonnees["case_titre_nom_police"], size=self.parent.dictDonnees["case_titre_taille_police"]-2)
            self.canvas.drawString(4, self.hauteur_case - y - 10, nom_categorie)
            self.canvas.restoreState()


        # Propriétés
        self.canvas.setFillColor(ColorWxToPdf(self.parent.dictDonnees["case_texte_couleur"], alpha=1))

        # Création des paragraphes
        taille_police = self.parent.dictDonnees["case_taille_police"]
        espace_vertical = self.parent.dictDonnees["case_espace_vertical"]
        liste_paragraphes, hauteur_paragraphes = self.GetParagraphes(texte, taille_police)
        ratio_depassement = (hauteur_paragraphes + (len(liste_paragraphes) - 1) * espace_vertical) / hauteur

        # Vérifie si le texte ne dépasse pas de la case
        if ratio_depassement > 1 :
            taille_police = taille_police / ratio_depassement
            liste_paragraphes, hauteur_paragraphes = self.GetParagraphes(texte, taille_police)

        # Calcule l'espace vertical et la marge supérieure
        if self.parent.dictDonnees["case_repartition_verticale"] == True :
            # marge_haut = self.parent.dictDonnees["case_marge_haut"]
            # espace_vertical = (hauteur - hauteur_paragraphes - marge_haut * 2) / (len(liste_paragraphes) - 1)
            bordure = 4
            espace_vertical = (hauteur - hauteur_paragraphes - bordure*2) / (len(liste_paragraphes) - 1 + 2)
            marge_haut = espace_vertical + bordure
        else :
            espace_vertical = self.parent.dictDonnees["case_espace_vertical"]
            marge_haut = (hauteur - (hauteur_paragraphes + (len(liste_paragraphes) - 1) * espace_vertical)) / 2.0

        # Préparation des images
        if self.parent.dictDonnees["case_separateur_type"] == "image" and self.parent.dictDonnees["case_separateur_image"] != "aucune":
            img = wx.Image(Chemins.GetStaticPath("Images/Menus/%s" % self.parent.dictDonnees["case_separateur_image"]), wx.BITMAP_TYPE_ANY)
            ratio_image = 1.0 * img.GetWidth() / img.GetHeight()
            largeur_image = self.largeur_case / 1.5
            hauteur_image = largeur_image / ratio_image
            separateur_image = Image(Chemins.GetStaticPath("Images/Menus/%s" % self.parent.dictDonnees["case_separateur_image"]), width=largeur_image, height=hauteur_image)

        # Dessine les lignes
        y_paragraphe = self.hauteur_case - y - marge_haut
        index = 0
        for hauteur_paragraphe, paragraphe in liste_paragraphes:
            y_paragraphe -= hauteur_paragraphe
            paragraphe.drawOn(self.canvas, 0, y_paragraphe)

            # Dessine l'image de séparation
            if self.parent.dictDonnees["case_separateur_type"] != "aucun" and index < len(liste_paragraphes) - 1:
                if self.parent.dictDonnees["case_separateur_type"] == "image" :
                    separateur_image.drawOn(self.canvas, self.largeur_case / 2.0 - separateur_image._width / 2.0, y_paragraphe - espace_vertical / 2.0 - separateur_image._height / 2.0)
                elif self.parent.dictDonnees["case_separateur_type"] == "ligne":
                    largeur_separateur = self.largeur_case / 3.5
                    x_separateur = (self.largeur_case - largeur_separateur) / 2.0
                    self.canvas.setStrokeColor(ColorWxToPdf(wx.WHITE, alpha=0.2))
                    self.canvas.setLineWidth(0.25)
                    self.canvas.line(x_separateur, y_paragraphe - espace_vertical / 2.0, x_separateur + largeur_separateur, y_paragraphe - espace_vertical / 2.0)

            y_paragraphe -= espace_vertical
            index += 1
Ejemplo n.º 53
0
    def __init__(self, dictValeurs={}, dictOptions={}, IDmodele=None, mode="facture", ouverture=True, nomFichier=None, titre=None):
        """ Impression """
        global DICT_VALEURS, DICT_OPTIONS
        DICT_VALEURS = dictValeurs
        DICT_OPTIONS = dictOptions
        self.mode = mode
        
        detail = 0
        if dictOptions["affichage_prestations"] != None :
            detail = dictOptions["affichage_prestations"]
        
        # Initialisation du document
        if nomFichier == None :
            nomDoc = _(u"Temp/%ss_%s.pdf") % (mode, FonctionsPerso.GenerationIDdoc())
        else :
            nomDoc = nomFichier
        doc = BaseDocTemplate(nomDoc, pagesize=TAILLE_PAGE, showBoundary=False)
        
        # Mémorise le ID du modèle
        modeleDoc = DLG_Noedoc.ModeleDoc(IDmodele=IDmodele)
        doc.modeleDoc = modeleDoc

        # Vérifie qu'un cadre principal existe bien dans le document
        if doc.modeleDoc.FindObjet("cadre_principal") == None :
            raise Exception("Votre modèle de document doit obligatoirement comporter un cadre principal. Retournez dans l'éditeur de document et utilisez pour votre modèle la commande 'Insérer un objet spécial > Insérer le cadre principal'.")
        
        # Importe le template de la première page
        doc.addPageTemplates(MyPageTemplate(pageSize=TAILLE_PAGE, doc=doc))
        
        story = []
        styleSheet = getSampleStyleSheet()
        h3 = styleSheet['Heading3']
        styleTexte = styleSheet['BodyText'] 
        styleTexte.fontName = "Helvetica"
        styleTexte.fontSize = 9
        styleTexte.borderPadding = 9
        styleTexte.leading = 12
        
##        # Définit le template des pages suivantes
##        story.append(NextPageTemplate("suivante"))
        
        
        # ----------- Insertion du contenu des frames --------------
        listeNomsSansCivilite = []
        for IDcompte_payeur, dictValeur in dictValeurs.iteritems() :
            listeNomsSansCivilite.append((dictValeur["nomSansCivilite"], IDcompte_payeur))
        listeNomsSansCivilite.sort() 
        
        for nomSansCivilite, IDcompte_payeur in listeNomsSansCivilite :
            dictValeur = dictValeurs[IDcompte_payeur]
            if dictValeur["select"] == True :
                
                story.append(DocAssign("IDcompte_payeur", IDcompte_payeur))
                nomSansCivilite = dictValeur["nomSansCivilite"]
                story.append(Bookmark(nomSansCivilite, str(IDcompte_payeur)))
                
                # ------------------- TITRE -----------------
                if dictOptions["afficher_titre"] == True :
                    if titre == None :
                        if mode == "facture" : titre = _(u"Facture")
                        if mode == "attestation" : titre = _(u"Attestation de présence")
                        if dictValeur.has_key("texte_titre") : 
                            titre = dictValeur["texte_titre"]
                    dataTableau = []
                    largeursColonnes = [ CADRE_CONTENU[2], ]
                    dataTableau.append((titre,))
                    texteDateDebut = DateEngFr(str(dictValeur["date_debut"]))
                    texteDateFin = DateEngFr(str(dictValeur["date_fin"]))
                    if dictOptions["afficher_periode"] == True :
                        dataTableau.append((_(u"Période du %s au %s") % (texteDateDebut, texteDateFin),))
                    styles = [
                            ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), 
                            ('FONT',(0,0),(0,0), "Helvetica-Bold", dictOptions["taille_texte_titre"]), 
                            ('LINEBELOW', (0,0), (0,0), 0.25, colors.black), 
                            ('ALIGN', (0,0), (-1,-1), 'LEFT'), 
                            ]
                    
                    if dictOptions["afficher_periode"] == True :
                        styles.append(('FONT',(0,1),(0,1), "Helvetica", dictOptions["taille_texte_periode"]))
                    tableau = Table(dataTableau, largeursColonnes)
                    tableau.setStyle(TableStyle(styles))
                    story.append(tableau)
                    story.append(Spacer(0,20))
                
                # TEXTE D'INTRODUCTION pour Attestation
##                if mode == "attestation" and dictValeur["intro"] != None :
##                    texteIntro = dictValeur["intro"]
##                    paraStyle = ParagraphStyle(name="intro",
##                                          fontName="Helvetica",
##                                          fontSize=9,
##                                          leading=14,
##                                          spaceBefore=0,
##                                          spaceafter=0,
##                                          leftIndent=20,
##                                          rightIndent=20,
##                                          alignment=1,
##                                        )
##                    story.append(Paragraph(u"<i>%s</i>" % texteIntro, paraStyle))
##                    story.append(Spacer(0,20))

                if dictOptions["texte_introduction"] != "" :
                    paraStyle = ParagraphStyle(name="introduction",
                                          fontName="Helvetica",
                                          fontSize=dictOptions["taille_texte_introduction"],
                                          leading=14,
                                          spaceBefore=0,
                                          spaceafter=0,
                                          leftIndent=5,
                                          rightIndent=5,
                                          alignment=dictOptions["alignement_texte_introduction"],
                                          backColor=ConvertCouleurWXpourPDF(dictOptions["couleur_fond_introduction"]),
                                          borderColor=ConvertCouleurWXpourPDF(dictOptions["couleur_bord_introduction"]),
                                          borderWidth=0.5,
                                          borderPadding=5,
                                        )
                    texte = dictValeur["texte_introduction"].replace("\\n", "<br/>")
                    if dictOptions["style_texte_introduction"] == 0 : texte = u"<para>%s</para>" % texte
                    if dictOptions["style_texte_introduction"] == 1 : texte = u"<para><i>%s</i></para>" % texte
                    if dictOptions["style_texte_introduction"] == 2 : texte = u"<para><b>%s</b></para>" % texte
                    if dictOptions["style_texte_introduction"] == 3 : texte = u"<para><i><b>%s</b></i></para>" % texte
                    story.append(Paragraph(texte, paraStyle))
                    story.append(Spacer(0,20))

                    
                couleurFond = ConvertCouleurWXpourPDF(dictOptions["couleur_fond_1"]) # (0.8, 0.8, 1)
                couleurFondActivite = ConvertCouleurWXpourPDF(dictOptions["couleur_fond_2"]) # (0.92, 0.92, 1)

                # ------------------- TABLEAU CONTENU -----------------
                montantPeriode = FloatToDecimal(0.0)
                montantVentilation = FloatToDecimal(0.0)

                # Recherche si TVA utilisée
                activeTVA = False
                for IDindividu, dictIndividus in dictValeur["individus"].iteritems() :
                    for IDactivite, dictActivites in dictIndividus["activites"].iteritems() :
                        for date, dictDates in dictActivites["presences"].iteritems() :
                            for dictPrestation in dictDates["unites"] :
                                if dictPrestation["tva"] != None and dictPrestation["tva"] != 0.0 :
                                    activeTVA = True

                # Remplissage
                for IDindividu, dictIndividus in dictValeur["individus"].iteritems() :
                    
                    if dictIndividus["select"] == True :
                        
                        listeIndexActivites = []
                        montantPeriode += dictIndividus["total"]
                        montantVentilation += dictIndividus["ventilation"]
                        
                        # Initialisation des largeurs de tableau
                        largeurColonneDate = dictOptions["largeur_colonne_date"]
                        largeurColonneMontantHT = dictOptions["largeur_colonne_montant_ht"]
                        largeurColonneTVA = dictOptions["largeur_colonne_montant_tva"]
                        largeurColonneMontantTTC = dictOptions["largeur_colonne_montant_ttc"]
                        largeurColonneBaseTTC = largeurColonneMontantTTC
                        
                        if activeTVA == True and detail == 0 :
                            largeurColonneIntitule = CADRE_CONTENU[2] - largeurColonneDate - largeurColonneMontantHT - largeurColonneTVA - largeurColonneMontantTTC
                            largeursColonnes = [ largeurColonneDate, largeurColonneIntitule, largeurColonneMontantHT, largeurColonneTVA, largeurColonneMontantTTC]
                        else :
                            if detail != 0 :
                                largeurColonneIntitule = CADRE_CONTENU[2] - largeurColonneDate - largeurColonneBaseTTC - largeurColonneMontantTTC
                                largeursColonnes = [ largeurColonneDate, largeurColonneIntitule, largeurColonneBaseTTC, largeurColonneMontantTTC]
                            else :
                                largeurColonneIntitule = CADRE_CONTENU[2] - largeurColonneDate - largeurColonneMontantTTC
                                largeursColonnes = [ largeurColonneDate, largeurColonneIntitule, largeurColonneMontantTTC]
                        
                        # Insertion du nom de l'individu
                        paraStyle = ParagraphStyle(name="individu",
                                              fontName="Helvetica",
                                              fontSize=dictOptions["taille_texte_individu"],
                                              leading=dictOptions["taille_texte_individu"],
                                              spaceBefore=0,
                                              spaceafter=0,
                                            )
                        texteIndividu = Paragraph(dictIndividus["texte"], paraStyle)
                        dataTableau = []
                        dataTableau.append([texteIndividu,])
                        tableau = Table(dataTableau, [CADRE_CONTENU[2],])
                        listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", dictOptions["taille_texte_individu"]), 
                                ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                                ('BACKGROUND', (0, 0), (-1, 0), couleurFond),
                                ]
                        tableau.setStyle(TableStyle(listeStyles))
                        story.append(tableau)
                        
                        # Insertion du nom de l'activité
                        for IDactivite, dictActivites in dictIndividus["activites"].iteritems() :
                            texteActivite = dictActivites["texte"]
                            if texteActivite != None :
                                dataTableau = []
                                dataTableau.append([texteActivite,])
                                tableau = Table(dataTableau, [CADRE_CONTENU[2],])
                                listeStyles = [
                                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                    ('FONT', (0, 0), (-1, -1), "Helvetica", dictOptions["taille_texte_activite"]),
                                    ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                                    ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                                    ('BACKGROUND', (0, 0), (-1, 0), couleurFondActivite),
                                    ]
                                tableau.setStyle(TableStyle(listeStyles))
                                story.append(tableau)

                            # Style de paragraphe normal
                            paraStyle = ParagraphStyle(name="prestation",
                                          fontName="Helvetica",
                                          fontSize=dictOptions["taille_texte_prestation"],
                                          leading=dictOptions["taille_texte_prestation"],
                                          spaceBefore=0,
                                          spaceAfter=0,
                                          )

                            paraLabelsColonnes = ParagraphStyle(name="paraLabelsColonnes",
                                          fontName="Helvetica",
                                          fontSize=dictOptions["taille_texte_noms_colonnes"],
                                          leading=dictOptions["taille_texte_noms_colonnes"],
                                          spaceBefore=0,
                                          spaceAfter=0,
                                          )
                                

                            if detail != 0 :
                                
                                # -------------- MODE REGROUPE ----------------
                                
                                # Regroupement par prestations identiques
                                dictRegroupement = {}
                                for date, dictDates in dictActivites["presences"].iteritems() :
                                    total = dictDates["total"]
                                    for dictPrestation in dictDates["unites"] :
                                        label = dictPrestation["label"]
                                        listeDatesUnite = GetDatesListes(dictPrestation["listeDatesConso"])
                                        montant = dictPrestation["montant"]
                                        deductions = dictPrestation["deductions"]
                                        tva = dictPrestation["tva"]
                                        
                                        if detail == 1 : labelkey = label
                                        if detail == 2 : labelkey = label + " P.U. " + "%.2f %s" % (montant, SYMBOLE)
                                            
                                        if dictRegroupement.has_key(labelkey) == False :
                                            dictRegroupement[labelkey] = {"labelpresta" : label, "total" : 0, "nbre" : 0, "base" : 0, "dates_forfait" : None}
                                            dictRegroupement[labelkey]["base"] = montant
                                        
                                        dictRegroupement[labelkey]["total"] += montant
                                        dictRegroupement[labelkey]["nbre"] += 1
                                        
                                        if detail == 1 :
                                            dictRegroupement[labelkey]["base"] = dictRegroupement[labelkey]["total"] / dictRegroupement[labelkey]["nbre"]
 
                                        if len(listeDatesUnite) > 1 :
                                            listeDatesUnite.sort()
                                            date_debut = listeDatesUnite[0]
                                            date_fin = listeDatesUnite[-1]
                                            nbreDates = len(listeDatesUnite)
                                            dictRegroupement[labelkey]["dates_forfait"] = _(u"<BR/><font size=5>Du %s au %s soit %d jours</font>") % (DateEngFr(str(date_debut)), DateEngFr(str(date_fin)), nbreDates)
        
                                # Insertion des prestations regroupées
                                listeLabels = dictRegroupement.keys() 
                                listeLabels.sort() 

                                dataTableau = [(
                                    Paragraph(_(u"<para align='center'>Quantité</para>"), paraLabelsColonnes), 
                                    Paragraph(_(u"<para align='center'>Prestation</para>"), paraLabelsColonnes),
                                    Paragraph(_(u"<para align='center'>Base</para>"), paraLabelsColonnes),
                                    Paragraph(_(u"<para align='center'>Montant</para>"), paraLabelsColonnes), 
                                    ),]

                                for labelkey in listeLabels :
                                    label = dictRegroupement[labelkey]["labelpresta"]
                                    nbre = dictRegroupement[labelkey]["nbre"]
                                    total = dictRegroupement[labelkey]["total"]
                                    base = dictRegroupement[labelkey]["base"]

                                    # recherche d'un commentaire
                                    if dictOptions.has_key("dictCommentaires") :
                                        key = (label, IDactivite)
                                        if dictOptions["dictCommentaires"].has_key(key) :
                                            commentaire = dictOptions["dictCommentaires"][key]
                                            label = "%s <i><font color='#939393'>%s</font></i>" % (label, commentaire)
                                            
                                    # Formatage du label
                                    intitule = Paragraph(label, paraStyle)
                                    
                                    # Rajout des dates de forfait
                                    #dates_forfait = dictRegroupement[label]["dates_forfait"]
                                    #if dates_forfait != None :
                                    #    intitule = [intitule, Paragraph(dates_forfait, paraStyle)]

                                    dataTableau.append([Paragraph(u"<para align='center'>%d</para>" % nbre, paraStyle), intitule, Paragraph(u"<para align='center'>%.02f %s</para>" % (base, SYMBOLE), paraStyle), Paragraph(u"<para align='center'>%.02f %s</para>" % (total, SYMBOLE), paraStyle)])
 
                            else :
                                
                                # -------------------------------------------------------------- MODE DETAILLE ------------------------------------------------------------------


                                # Insertion de la date
                                listeDates = []
                                for date, dictDates in dictActivites["presences"].iteritems() :
                                    listeDates.append(date)
                                listeDates.sort() 
                                
                                paraStyle = ParagraphStyle(name="prestation",
                                              fontName="Helvetica",
                                              fontSize=dictOptions["taille_texte_prestation"],
                                              leading=dictOptions["taille_texte_prestation"],
                                              spaceBefore=0,
                                              spaceAfter=0,
                                              )

                                dataTableau = []

                                if activeTVA == True :
                                    dataTableau.append([
                                        Paragraph(_(u"<para align='center'>Date</para>"), paraLabelsColonnes), 
                                        Paragraph(_(u"<para align='center'>Prestation</para>"), paraLabelsColonnes), 
                                        Paragraph(_(u"<para align='center'>Montant HT</para>"), paraLabelsColonnes), 
                                        Paragraph(_(u"<para align='center'>Taux TVA</para>"), paraLabelsColonnes), 
                                        Paragraph(_(u"<para align='center'>Montant TTC</para>"), paraLabelsColonnes), 
                                        ])

                                for date in listeDates :
                                    dictDates = dictActivites["presences"][date]
                                    
                                    date = dictDates["texte"]
                                    prestations = dictDates["unites"]
                                    
                                    # Insertion des unités de présence
                                    listeIntitules = []
                                    listeMontantsHT = []
                                    listeTVA = []
                                    listeMontantsTTC = []
                                    texteIntitules = u""
                                    texteMontantsHT = u""
                                    texteTVA = u""
                                    texteMontantsTTC = u""
                                    
                                    for dictPrestation in prestations :
                                        label = dictPrestation["label"]
                                        listeDatesUnite = GetDatesListes(dictPrestation["listeDatesConso"])
                                        montant_initial = dictPrestation["montant_initial"]
                                        montant = dictPrestation["montant"]
                                        deductions = dictPrestation["deductions"]
                                        tva = dictPrestation["tva"]

                                        # Date
                                        texteDate = Paragraph("<para align='center'>%s</para>" % date, paraStyle)
                                        
                                        # recherche d'un commentaire
                                        if dictOptions.has_key("dictCommentaires") :
                                            key = (label, IDactivite)
                                            if dictOptions["dictCommentaires"].has_key(key) :
                                                commentaire = dictOptions["dictCommentaires"][key]
                                                label = "%s <i><font color='#939393'>%s</font></i>" % (label, commentaire)

                                        # Affiche le Label de la prestation
                                        listeIntitules.append(Paragraph(label, paraStyle)) 
                                        
                                        # Recherche si c'est un forfait
                                        if len(listeDatesUnite) > 1 :
                                            listeDatesUnite.sort()
                                            date_debut = listeDatesUnite[0]
                                            date_fin = listeDatesUnite[-1]
                                            nbreDates = len(listeDatesUnite)
                                            label = _(u"<BR/><font size=5>Du %s au %s soit %d jours</font>") % (DateEngFr(str(date_debut)), DateEngFr(str(date_fin)), nbreDates)
                                            listeIntitules.append(Paragraph(label, paraStyle)) 
                                                                                
                                        # TVA
                                        if activeTVA == True :
                                            if tva == None : tva = 0.0
                                            montantHT = (100.0 * float(montant)) / (100 + float(tva)) #montant - montant * 1.0 * float(tva) / 100
                                            listeMontantsHT.append(Paragraph(u"<para align='center'>%.02f %s</para>" % (montantHT, SYMBOLE), paraStyle))
                                            listeTVA.append(Paragraph(u"<para align='center'>%.02f %%</para>" % tva, paraStyle))
                                        else :
                                            listeMontantsHT.append("")
                                            listeTVA.append("")
                                            
                                        # Affiche total
                                        listeMontantsTTC.append(Paragraph(u"<para align='center'>%.02f %s</para>" % (montant, SYMBOLE), paraStyle)) 
                                    
                                        # Déductions
                                        if len(deductions) > 0 :
                                            for dictDeduction in deductions :
                                                listeIntitules.append(Paragraph(u"<para align='left'><font size=5 color='#939393'>- %.02f %s : %s</font></para>" % (dictDeduction["montant"], SYMBOLE, dictDeduction["label"]), paraStyle))
                                                #listeIntitules.append(Paragraph(u"<para align='left'><font size=5 color='#939393'>%s</font></para>" % dictDeduction["label"], paraStyle))
                                                listeMontantsHT.append(Paragraph("&nbsp;", paraStyle))
                                                listeTVA.append(Paragraph("&nbsp;", paraStyle))
                                                listeMontantsTTC.append(Paragraph("&nbsp;", paraStyle))
                                                #listeMontantsTTC.append(Paragraph(u"<para align='center'><font size=5 color='#939393'>- %.02f %s</font></para>" % (dictDeduction["montant"], SYMBOLE), paraStyle)) 
                                                
                                        
                                    if len(listeIntitules) == 1 :
                                        texteIntitules = listeIntitules[0]
                                        texteMontantsHT = listeMontantsHT[0]
                                        texteTVA = listeTVA[0]
                                        texteMontantsTTC = listeMontantsTTC[0]
                                    if len(listeIntitules) > 1 :
                                        texteIntitules = listeIntitules
                                        texteMontantsHT = listeMontantsHT
                                        texteTVA = listeTVA
                                        texteMontantsTTC = listeMontantsTTC
                                                                        
                                    if activeTVA == True :
                                        dataTableau.append([texteDate, texteIntitules, texteMontantsHT, texteTVA, texteMontantsTTC])
                                    else :
                                        dataTableau.append([texteDate, texteIntitules, texteMontantsTTC])
                                    
                            # Style du tableau des prestations
                            tableau = Table(dataTableau, largeursColonnes)
                            listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", dictOptions["taille_texte_prestation"]), 
                                ('GRID', (0, 0), (-1,-1), 0.25, colors.black), 
                                ('ALIGN', (0, 0), (-1, -1), 'CENTRE'),
                                ('ALIGN', (1, 0), (1, -1), 'LEFT'),
                                ('TOPPADDING', (0, 0), (-1, -1), 1), 
                                ('BOTTOMPADDING', (0, 0), (-1, -1), 3), 
                                ]
                            tableau.setStyle(TableStyle(listeStyles))
                            story.append(tableau)
                        
                        # Insertion des totaux
                        dataTableau = []
                        if activeTVA == True and detail == 0 :
                            dataTableau.append(["", "", "", "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], SYMBOLE) , paraStyle)])
                        else :
                            if detail != 0 :
                                dataTableau.append(["", "", "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], SYMBOLE) , paraStyle)])
                            else :
                                dataTableau.append(["", "", Paragraph("<para align='center'>%.02f %s</para>" % (dictIndividus["total"], SYMBOLE) , paraStyle)])
                        
                        listeStyles = [
                                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                ('FONT', (0, 0), (-1, -1), "Helvetica", dictOptions["taille_texte_prestation"]), 
                                ('GRID', (-1, -1), (-1,-1), 0.25, colors.black), 
                                ('ALIGN', (-1, -1), (-1, -1), 'CENTRE'),
                                ('BACKGROUND', (-1, -1), (-1, -1), couleurFond), 
                                ('TOPPADDING', (0, 0), (-1, -1), 1), 
                                ('BOTTOMPADDING', (0, 0), (-1, -1), 3), 
                                ]
                            
                        # Création du tableau
                        tableau = Table(dataTableau, largeursColonnes)
                        tableau.setStyle(TableStyle(listeStyles))
                        story.append(tableau)
                        story.append(Spacer(0, 10))
                
                # Intégration des messages, des reports et des qf
                listeMessages = []
                paraStyle = ParagraphStyle(name="message",
                                          fontName="Helvetica",
                                          fontSize=dictOptions["taille_texte_messages"],
                                          leading=dictOptions["taille_texte_messages"],
                                          #spaceBefore=0,
                                          spaceAfter=2,
                                        )
                
                # Date d'échéance
##                if dictOptions["echeance"] != None :
##                    listeMessages.append(Paragraph(dictOptions["echeance"], paraStyle))

               # QF aux dates de facture
                if mode == "facture" and dictOptions["afficher_qf_dates"] == True :
                    dictQfdates = dictValeur["qfdates"]
                    listeDates = dictQfdates.keys() 
                    listeDates.sort() 
                    if len(listeDates) > 0 :
                        for dates in listeDates :
                            texteQf = _(u"--- Votre QF %s : <b>%s</b> ---") % (dates, dictQfdates[dates])
                            listeMessages.append(Paragraph(texteQf, paraStyle))
                
                
                # Reports
                if mode == "facture" and dictOptions["afficher_impayes"] == True :
                    dictReports = dictValeur["reports"]
                    listePeriodes = dictReports.keys() 
                    listePeriodes.sort() 
                    if len(listePeriodes) > 0 :
                        texteReport = _(u"<b>Impayés : </b>Merci de bien vouloir nous retourner également le règlement des prestations antérieures : ")
                        for periode in listePeriodes :
                            annee, mois = periode
                            nomPeriode = PeriodeComplete(mois, annee)
                            montant_impaye = dictReports[periode]
                            texteReport += u"%s (%.02f %s), " % (nomPeriode, montant_impaye, SYMBOLE)
                        texteReport = texteReport[:-2] + u"."
                        listeMessages.append(Paragraph(texteReport, paraStyle))
                
                # Messages
                if mode == "facture" :
                    if dictOptions["afficher_messages"] == True :
                        for message in dictOptions["messages"] :
                            listeMessages.append(Paragraph(message, paraStyle))
                        
                        for message_familial in dictValeur["messages_familiaux"] :
                            texte = message_familial["texte"]
                            if len(texte) > 0 and texte[-1] not in ".!?" : 
                                texte = texte + u"."
                            texte = _(u"<b>Message : </b>%s") % texte
                            listeMessages.append(Paragraph(texte, paraStyle))
                            
                if len(listeMessages) > 0 :
                    listeMessages.insert(0, Paragraph(_(u"<u>Informations :</u>"), paraStyle))
                
                # ------------------ CADRE TOTAUX ------------------------
                dataTableau = []
                largeurColonneLabel = 110
                largeursColonnes = [ CADRE_CONTENU[2] - largeurColonneMontantTTC - largeurColonneLabel, largeurColonneLabel, largeurColonneMontantTTC]

                dataTableau.append((listeMessages, _(u"TOTAL période:"), u"%.02f %s" % (dictValeur["total"], SYMBOLE)))
                dataTableau.append(("", _(u"Montant déjà réglé :"), u"%.02f %s" % (dictValeur["ventilation"], SYMBOLE)))
                dataTableau.append(("", _(u"Reste à régler :"), u"%.02f %s" % (dictValeur["solde"], SYMBOLE) ))

                style = [
                        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), 
                        ('FONT', (1, 0), (1, -1), "Helvetica-Bold", dictOptions["taille_texte_labels_totaux"]), 
                        ('FONT', (2, 0), (2, -1), "Helvetica-Bold", dictOptions["taille_texte_montants_totaux"]), 
                        
                        ('GRID', (2, 0), (2, 0), 0.25, colors.black),
                        ('GRID', (2, 1), (2, 1), 0.25, colors.black),
                        ('GRID', (2, 2), (2, 2), 0.25, colors.black),
                        
                        ('ALIGN', (1, 0), (1, -1), 'RIGHT'),
                        ('ALIGN', (2, 0), (2, -1), 'CENTRE'), 
                        ('BACKGROUND', (2, 2), (2, 2), couleurFond),
                        
                        ('SPAN', (0, 0), (0, -1)), 
                        ]
                
                if mode == "facture" and len(listeMessages) > 0 :
                    #style.append( ('BACKGROUND', (0, 0), (0, 0), couleurFondActivite) )
                    style.append( ('FONT', (0, 0), (0, -1), "Helvetica", 8)  )
                    style.append( ('VALIGN', (0, 0), (0, -1), 'TOP') )
                    
                tableau = Table(dataTableau, largeursColonnes, rowHeights=[18, 18, None])
                tableau.setStyle(TableStyle(style))
                story.append(tableau)
                
                # ------------------------- PRELEVEMENTS --------------------
                if dictOptions.has_key("afficher_avis_prelevements") and dictValeur.has_key("prelevement") :
                    if dictValeur["prelevement"] != None and dictOptions["afficher_avis_prelevements"] == True :
                        paraStyle = ParagraphStyle(name="intro",
                              fontName="Helvetica",
                              fontSize=8,
                              leading=11,
                              spaceBefore=2,
                              spaceafter=2,
                              alignment=1,
                              backColor=couleurFondActivite,
                            )
                        story.append(Spacer(0,20))
                        story.append(Paragraph(u"<para align='center'><i>%s</i></para>" % dictValeur["prelevement"], paraStyle))
                
                # Texte conclusion
                if dictOptions["texte_conclusion"] != "" :
                    story.append(Spacer(0,20))
                    paraStyle = ParagraphStyle(name="conclusion",
                                          fontName="Helvetica",
                                          fontSize=dictOptions["taille_texte_conclusion"],
                                          leading=14,
                                          spaceBefore=0,
                                          spaceafter=0,
                                          leftIndent=5,
                                          rightIndent=5,
                                          alignment=dictOptions["alignement_texte_conclusion"],
                                          backColor=ConvertCouleurWXpourPDF(dictOptions["couleur_fond_conclusion"]),
                                          borderColor=ConvertCouleurWXpourPDF(dictOptions["couleur_bord_conclusion"]),
                                          borderWidth=0.5,
                                          borderPadding=5,
                                        )
            
                    texte = dictValeur["texte_conclusion"].replace("\\n", "<br/>")
                    if dictOptions["style_texte_conclusion"] == 0 : texte = u"<para>%s</para>" % texte
                    if dictOptions["style_texte_conclusion"] == 1 : texte = u"<para><i>%s</i></para>" % texte
                    if dictOptions["style_texte_conclusion"] == 2 : texte = u"<para><b>%s</b></para>" % texte
                    if dictOptions["style_texte_conclusion"] == 3 : texte = u"<para><i><b>%s</b></i></para>" % texte
                    story.append(Paragraph(texte, paraStyle))
                    
                # Image signature
                if dictOptions["image_signature"] != "" :
                    cheminImage = dictOptions["image_signature"]
                    if os.path.isfile(cheminImage) :
                        img = Image(cheminImage)
                        largeur, hauteur = int(img.drawWidth * 1.0 * dictOptions["taille_image_signature"] / 100.0), int(img.drawHeight * 1.0 * dictOptions["taille_image_signature"] / 100.0)
                        if largeur > CADRE_CONTENU[2] or hauteur > CADRE_CONTENU[3] :
                            raise Exception(_(u"L'image de signature est trop grande. Veuillez diminuer sa taille avec le parametre Taille."))
                        img.drawWidth, img.drawHeight = largeur, hauteur
                        if dictOptions["alignement_image_signature"] == 0 : img.hAlign = "LEFT"
                        if dictOptions["alignement_image_signature"] == 1 : img.hAlign = "CENTER"
                        if dictOptions["alignement_image_signature"] == 2 : img.hAlign = "RIGHT"
                        story.append(Spacer(0,20))
                        story.append(img)
                        


                # Saut de page
                story.append(PageBreak())

        # Finalisation du PDF
##        try :
        doc.build(story)
##        except Exception, err :
##            print "Erreur dans ouverture PDF :", err
##            if "Permission denied" in err :
##                dlg = wx.MessageDialog(None, _(u"Noethys ne peut pas créer le PDF.\n\nVeuillez vérifier qu'un autre PDF n'est pas déjà ouvert en arrière-plan..."), _(u"Erreur d'édition"), wx.OK | wx.ICON_ERROR)
##                dlg.ShowModal()
##                dlg.Destroy()
##                return
        
        # Ouverture du PDF
        if ouverture == True :
            FonctionsPerso.LanceFichierExterne(nomDoc)
Ejemplo n.º 54
0
    def fill(self):
        from django.template.defaultfilters import date as format_date, floatformat
        from reportlab.platypus.flowables import Image
        from core.pdf.utils import Paragraph
        from invoicing import currency_format

        # Sender frame
        # Sender identity
        sender_paragraphs = []
        if self.invoice_base.current_revision.sender:
            sender_paragraphs.append(Paragraph(self.invoice_base.current_revision.sender, self.style['Small']))
        sender_paragraphs.append(Paragraph(self.invoice_base.tenant.name, self.style['Small']))
        if self.invoice_base.current_revision.sender_address:
            sender_paragraphs.append(Paragraph(u'\n'.join(self.invoice_base.current_revision.sender_address.get_formatted()), self.style['Small']))
        # Add layout table if logo or paragraphs
        if self.invoice_base.tenant.logo_cache:
            logo = Image(self.invoice_base.tenant.logo_cache)
            logo_width, logo_height = logo._restrictSize(50 * mm, 20 * mm)
            self.table(
                [[logo, sender_paragraphs]],
                (logo_width + 4 * mm, None),
                self.style['LayoutTable'],
                rowHeights=(20 * mm,)
            )
        else:
            for paragraph in sender_paragraphs:
                self.append(paragraph)

        # Billing address frame
        self.next_frame()
        if self.invoice_base.current_revision.contact:
            self.p(self.invoice_base.current_revision.contact.get_full_name(upper_name=True), style=self.style['Address'])
        if self.invoice_base.current_revision.organization:
            self.p(self.invoice_base.current_revision.organization.corporate_name, style=self.style['Address'])
        if self.invoice_base.current_revision.billing_address:
            self.p(u'\n'.join(self.invoice_base.current_revision.billing_address.get_formatted()), style=self.style['Address'])

        # Delivery address frame
        self.next_frame()
        if self.invoice_base.current_revision.contact:
            self.p(self.invoice_base.current_revision.contact.get_full_name(upper_name=True), style=self.style['Address'])
        if self.invoice_base.current_revision.organization:
            self.p(self.invoice_base.current_revision.organization.corporate_name, style=self.style['Address'])
        if self.invoice_base.current_revision.delivery_address:
            self.p(u'\n'.join(self.invoice_base.current_revision.delivery_address.get_formatted()), style=self.style['Address'])

        # Rest of the report
        self.next_frame()
        invoice_reference = pgettext('date', 'Undefined') if getattr(self.invoice_base, 'has_temporary_reference', None) else self.invoice_base.reference
        self.table([[
            ' '.join([unicode(self.invoice_base.RECORD_NAME).upper(), invoice_reference]),
            format_date(self.invoice_base.current_revision.invoicing_date, 'DATE_FORMAT')
        ]], (12 * cm, 5 * cm), style=self.style['InvoiceBaseReferencesTable'])

        self.spacer()
        rows = [[
            pgettext('table-headers', 'Description'),
            pgettext('table-headers', 'Qty'),
            pgettext('table-headers', 'Unit price (excl. tax)'),
            pgettext('table-headers', 'Tax'),
            pgettext('table-headers', 'Total (excl. tax)')
        ]]
        for item in self.invoice_base.current_revision.line_items:
            rows.append([
                item.description,
                floatformat(item.quantity, -2),
                currency_format(item.unit_price),
                '{0:.2%}'.format(item.tax.rate),
                currency_format(item.total_price, self.invoice_base.current_revision.currency.symbol)
            ])
        col_widths = (85 * mm, 20 * mm, 20 * mm, 20 * mm, 25 * mm)
        self.table(rows, col_widths, repeatRows=1, style=self.style['InvoiceBaseItemsTable'])

        self.spacer()
        rows = [[
            _('TOTAL (excl. tax)'),
            currency_format(self.invoice_base.sub_total, self.invoice_base.current_revision.currency.symbol)
        ]]
        for tax in self.invoice_base.taxes_amounts:
            rows.append([
                '%(tax_name)s (%(tax_rate)s)' % {
                    'tax_name': tax.get('name'),
                    'tax_rate': '{0:.2%}'.format(tax.get('rate'))
                },
                currency_format(tax.get('amount'), self.invoice_base.current_revision.currency.symbol)
            ])
        rows.append([
            _('TOTAL (incl. tax)'),
            currency_format(self.invoice_base.amount, self.invoice_base.current_revision.currency.symbol)
        ])
        col_widths = (None, 25 * mm)
        self.start_keeptogether()
        self.table(rows, col_widths, hAlign='RIGHT', style=self.style['InvoiceBaseSummaryTable'])
        self.end_keeptogether()

        # Legal notices
        self.spacer()
        self.start_keeptogether()
        if self.invoice_base.is_quotation():
            self.p(_("Valid until %(quotation_validity)s") % {
                'quotation_validity': format_date(self.invoice_base.current_revision.quotation_validity, 'DATE_FORMAT')
            })
        elif self.invoice_base.is_purchase_order():
            if self.invoice_base.group.quotation:
                self.p(_("Refers to quotation %(quotation_reference)s") % {
                    'quotation_reference': self.invoice_base.group.quotation.reference
                })
            else:
                self.p('')
        elif self.invoice_base.is_invoice() or self.invoice_base.is_down_payment_invoice():
            if self.invoice_base.current_revision.custom_payment_conditions:
                self.p(_("Payment conditions: %(custom_payment_conditions)s") % {
                    'custom_payment_conditions': self.invoice_base.current_revision.custom_payment_conditions
                })
            else:
                self.p(_("Payment due date on %(due_date)s") % {
                    'due_date': format_date(self.invoice_base.current_revision.due_date, 'DATE_FORMAT')
                })
            pt_dict = dict(PAYMENT_TYPES)
            invoicing_settings = self.invoice_base.tenant.tenant_settings.invoicing
            self.p(_("Accepted payment methods: %(accepted_payment_methods)s") % {
                'accepted_payment_methods': u', '.join([unicode(pt_dict.get(pt, pt)).lower() for pt in invoicing_settings.accepted_payment_types])
            })
            if invoicing_settings.late_fee_rate:
                self.p(_("Late fee rate: %(late_fee_rate)s") % {
                    'late_fee_rate': u'{0:.2%}'.format(invoicing_settings.late_fee_rate)
                })
            else:
                self.p(_("Late fee at the legal rate"))
        elif self.invoice_base.is_credit_note():
            self.p(_("Refers to invoice %(invoice_reference)s") % {
                'invoice_reference': self.invoice_base.group.invoice.reference
            })
        else:
            self.p('')
        self.end_keeptogether()

        # Registration information
        self.next_frame()
        registration_info_parts = [self.invoice_base.tenant.name] + self.invoice_base.tenant.registration_info.get_list()
        self.p(u' - '.join(registration_info_parts), style=self.style['Smaller'])

        # Metadata
        if self.invoice_base.issuer:
            self.doc.author = self.invoice_base.issuer.get_full_name()
        if self.invoice_base.reference:
            document_name = ' '.join([
                unicode(self.invoice_base.RECORD_NAME).upper(),
                self.invoice_base.reference
            ])
            self.doc.title = document_name
            self.doc.subject = document_name
        self.doc.creator = self.invoice_base.tenant.name
        self.doc.keywords = self.invoice_base.keywords
Ejemplo n.º 55
0
    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)
Ejemplo n.º 56
0
 def render_page2_image(self):
     A4_Width, A4_Height = A4
     self.im = Image(_self_path+ '/' + u'post2.JPG',width=A4_Height, height=A4_Width)
     self.im.drawOn(self.pdf, self.x(0), self.y(0))