def test0(self): "This makes one long multi-page paragraph." # Build story. story = [] styleSheet = getSampleStyleSheet() bt = styleSheet['BodyText'] text = '''If you imagine that the box of X's tothe left is an image, what I want to be able to do is flow a series of paragraphs around the image so that once the bottom of the image is reached, then text will flow back to the left margin. I know that it would be possible to something like this using tables, but I can't see how to have a generic solution. There are two examples of this in the demonstration section of the reportlab site. If you look at the "minimal" euro python conference brochure, at the end of the timetable section (page 8), there are adverts for "AdSu" and "O'Reilly". I can see how the AdSu one might be done generically, but the O'Reilly, unsure... I guess I'm hoping that I've missed something, and that it's actually easy to do using platypus. ''' from reportlab.platypus.flowables import ParagraphAndImage, Image from reportlab.lib.testutils import testsFolder gif = os.path.join(testsFolder,'pythonpowered.gif') story.append(ParagraphAndImage(Paragraph(text,bt),Image(gif))) phrase = 'This should be a paragraph spanning at least three pages. ' description = ''.join([('%d: '%i)+phrase for i in xrange(250)]) story.append(ParagraphAndImage(Paragraph(description, bt),Image(gif),side='left')) doc = MyDocTemplate(outputfile('test_platypus_paragraphandimage.pdf')) doc.multiBuild(story)
def 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)
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
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)
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)
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()
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, )
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, )
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)
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)
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)
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)])
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)
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)
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, )
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/> Christian Wichmann<br/> [email protected]""" ] # building document doc = SimpleDocTemplate(output_file, author=author, title=title) story = [] for t in teacher_list: user_data = '{} {}'.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)
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)
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)
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)
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 __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 )
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)
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)
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)
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)
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)
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)])
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)
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)
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()
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)]
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
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)
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
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 & BOTTOM, the blue RIGHT & TOP and the green CENTER & 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)
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)
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 <unichar code=0xfc/>="<unichar code="0xfc"/>" and this &#xfc;="ü" and this \\xc3\\xbc="\xc3\xbc". On the other hand this should be a pound sign &pound;="£" and this an alpha &alpha;="α". You can have links in the page <link href="http://www.reportlab.com" color="blue">ReportLab</link> & <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)
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 & BOTTOM, the blue RIGHT & TOP and the green CENTER & 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)
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))
def add_image(self, src, width, height, align=CENTER): img = Image(src, width, height) img.hAlign = align self.add(img)
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 wrap(self,availWidth,availHeight): h, w = Image.wrap(self,availHeight,availWidth) return w, h
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
def insertImage(self, imagePath, height, width): img = Image(imagePath) img.drawHeight = height img.drawWidth = width self.Story.append(img)
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)
def draw(self): self.canv.rotate(90) Image.draw(self)
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
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(" ", paraStyle)) listeTVA.append(Paragraph(" ", paraStyle)) listeMontantsTTC.append(Paragraph(" ", 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)
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
def Imprimer(self, event=None): listeDates = self.dictImpression["dates"] if len(listeDates) > 26 : dlg = wx.MessageDialog(self, _(u"Désolé mais vous ne pouvez pas imprimer plus de 26 jours sur une feuille !"), _(u"Information"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Création du PDF from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak from reportlab.platypus.flowables import ParagraphAndImage, Image from reportlab.rl_config import defaultPageSize from reportlab.lib.units import inch, cm from reportlab.lib.utils import ImageReader from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle self.hauteur_page = defaultPageSize[1] self.largeur_page = defaultPageSize[0] # Recherche le format de la page à appliquer largeurPremiereColonne = 140 largeurColonnesDates = 24 largeurMax = largeurPremiereColonne + (largeurColonnesDates*len(listeDates)) if largeurMax <= 520 : # Format Portrait largeurPage, hauteurPage = defaultPageSize largeurContenu = 520 else : # Format Paysage hauteurPage, largeurPage = defaultPageSize largeurContenu = 770 # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc("LISTE_TRANSPORTS", "pdf") if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=(largeurPage, hauteurPage), topMargin=30, bottomMargin=30) story = [] # Création du titre du document def Header(): dataTableau = [] largeursColonnes = ( (largeurContenu-100, 100) ) dateDuJour = DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Liste des transports"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour)) ) style = TableStyle([ ('BOX', (0,0), (-1,-1), 0.25, colors.black), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('ALIGN', (0,0), (0,0), 'LEFT'), ('FONT',(0,0),(0,0), "Helvetica-Bold", 16), ('ALIGN', (1,0), (1,0), 'RIGHT'), ('FONT',(1,0),(1,0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Insère un header Header() # Contenu for dictCategorie in self.dictImpression["donnees"] : label = dictCategorie["texte"] img = dictCategorie["img"] elements = dictCategorie["elements"] dataTableau = [] largeursColonnes = [largeurPremiereColonne,] # Création de la ligne de date paraStyle = ParagraphStyle(name="categorie", fontName="Helvetica-Bold", fontSize=9, leading=8, spaceAfter=2,) ligne = [ParagraphAndImage(Paragraph(label, paraStyle), Image(Chemins.GetStaticPath("Images/32x32/%s.png" % img), width=8, height=8), xpad=1, ypad=0, side="left"),] for date in listeDates : ligne.append(u"%02d/%02d\n%04d" % (date.day, date.month, date.year)) largeursColonnes.append(largeurColonnesDates) dataTableau.append(ligne) # Création des lignes listeExtraStyles = [] index = 1 for element in elements : # Décoration de la ligne if element["type"] in ("lieux", "lignes", "localisations") : listeExtraStyles.append(('BACKGROUND', (0, index), (-1, index), (0.8, 0.8, 1) )) if element["type"] == "arrets" : listeExtraStyles.append(('BACKGROUND', (0, index), (-1, index), (0.9, 0.9, 1) )) if element["type"] == "heures" : listeExtraStyles.append(('FONT',(0, index), (0, index), "Helvetica-Bold", 6),) listeExtraStyles.append(('FONT',(1, index), (-1, index), "Helvetica", 5),) listeExtraStyles.append(('TEXTCOLOR',(1, index), (-1, index), (0.6, 0.6, 0.6)),) if element["type"] == "individus" : listeExtraStyles.append(('ALIGN', (0, index), (0, index), 'RIGHT')) listeExtraStyles.append(('GRID', (1, index), (-1, index), 0.25, colors.black)) listeExtraStyles.append(('FONT',(1, index), (-1, index), "Helvetica", 6),) # Ajout d'une marge label = element["texte"] if "marge" in element : label = u"%s%s" % ((element["marge"]-1) * " ", label) ligne = [label,] # Ajout des colonnes for indexColonne in range(1, len(largeursColonnes)) : label = u"" if "colonnes" in element: if indexColonne in element["colonnes"] : label = element["colonnes"][indexColonne] ligne.append(label) dataTableau.append(ligne) index += 1 # Style du tableau listeStyles = [ ('VALIGN', (0, 0), (-1,-1), 'MIDDLE'), ('ALIGN', (1, 0), (-1, -1), 'CENTRE'), ('FONT',(0, 0), (-1,-1), "Helvetica", 7), ('FONT',(0, 0), (0, 0), "Helvetica-Bold", 8), ('BOX', (0, 1), (-1, -1), 0.25, colors.black), ('GRID', (1, 0), (-1, 0), 0.25, colors.black), ] for extraStyle in listeExtraStyles : listeStyles.append(extraStyle) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(TableStyle(listeStyles)) story.append(tableau) story.append(Spacer(0, 15)) ## # TOTAUX ## dataTableau = [] ## largeursColonnes = [220, 220, 40, 40] ## ## for ligne in self.listeImpression["totaux"] : ## dataTableau.append(ligne) ## ## couleurFond = (0.8, 0.8, 0.8) ## listeStyles = [ ## ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases ## ('FONT',(0,0),(-1,-1), "Helvetica", 7), # Donne la police de caract. + taille de police ## ('BOX', (0, 1), (-1,-1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau ## ('ALIGN', (2, 0), (-1, -1), 'CENTRE'), # Ligne de labels colonne alignée au centre ## ('BOX', (0, 0), (-1,0), 0.25, colors.black), # Crée la bordure noire du nom de famille ## ('FONT',(0,0),(0,0), "Helvetica-Bold", 8), # Donne la police de caract. + taille de police du titre de groupe ## ('BACKGROUND', (0,0), (-1,0), couleurFond), # Donne la couleur de fond du titre de groupe ## ('TOPPADDING',(0,0),(-1,-1), 1), ## ('BOTTOMPADDING',(0,0),(-1,-1), 1), ## ] ## ## # Création du tableau ## tableau = Table(dataTableau, largeursColonnes) ## tableau.setStyle(TableStyle(listeStyles)) ## story.append(tableau) # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)
def 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))