def _make_preorder_report(preorder,filename): # Session open ! s = ParagraphStyle(name = "regular", fontName = 'Helvetica', fontSize=11, spaceAfter=6) money = ParagraphStyle(name = "money", fontName = 'DejaVuSansMono', fontSize=11, spaceAfter=6,alignment=TA_RIGHT) right_align = ParagraphStyle(name = "right_align", fontName = 'Helvetica', fontSize=11,alignment=TA_RIGHT) complete_document = [] spacer = platypus.Spacer(1,1*cm) c = preorder.customer # Address frame p = Paragraph(escape_html(c.fullname),s) complete_document.append(p) p = Paragraph(escape_html(c.address1),s) complete_document.append(p) p = Paragraph(escape_html(c.address2),s) complete_document.append(p) p = Paragraph(escape_html(c.country),s) complete_document.append(p) complete_document.append(FrameBreak()) # Header frame title = "" if preorder.customer_order_name: title = _("Preorder {}, your ref. : {}").format(preorder.preorder_label or "-", escape_html(preorder.customer_order_name)) else: title = _("Preorder {}").format(preorder.preorder_label or "-") append_header_block(complete_document, title, date.today()) # Introduction text intro = preorder.preorder_print_note or "" p = Paragraph(escape_html(intro),s) complete_document.append(p) complete_document.append(spacer) # Well, by combining a MIDDLE VALIGN and a leading=20, I can get the # paragraph to be right in the middle of the cell (vertically speaking) # It doesn't make sense to me, it's pure trial and error... subtitle = ParagraphStyle(name = "subtitle", fontName = 'Helvetica', fontSize=16, leading=20) data_ops = [ [_(u'Reference'), '', _(u'Designation'),'',_('Deadline'),'',_('Quantity'),'',_('Unit Price'),'',_('Price')] ] # getcontext().prec = 2 with localcontext() as ctx: # decimal context ctx.prec = 10+2 qtize = Decimal(10)**-2 total = Decimal(0) for part in preorder.parts: price = Decimal(int(part.qty) * part.sell_price).quantize(qtize) total += price s_qty = '' if part.qty > 0: s_qty = str(int(part.qty)) s_price = '' if part.sell_price > 0 and part.qty > 0: s_price = moneyfmt(price) dl = "-" if part.deadline: dl = date_to_dmy(part.deadline) data_ops.append([Paragraph(u"<b>{}</b>".format(part.human_identifier),s), None, Paragraph(escape_html(part.description),s), None, Paragraph(dl,right_align), None, Paragraph(u"{}".format(s_qty),money), None, Paragraph(u"{}".format(moneyfmt(Decimal(part.sell_price).quantize(qtize))),money), None, Paragraph(u"{}".format(s_price),money)]) # data_ops.append([None, # None, # None, # None, # Paragraph(_("Total"),s), # None, # Paragraph(moneyfmt(total),money)]) t = MyTable(data_ops, repeatRows=1, colWidths=[2*cm,0.2*cm,6*cm,0.2*cm,2*cm,0.2*cm,1*cm,0.2*cm,3*cm,0.2*cm,3*cm]) # Repeat the table header t.spaceAfter = 1*cm ts = platypus.TableStyle([('FONT', (0, 0), (-1, -1), 'Helvetica-Bold', 12)]) ts.add('ALIGN', (0, 0), (-1, -1), 'LEFT') ts.add('VALIGN', (0, 0), (-1, -1), 'TOP') ts.add("LEFTPADDING", (0, 0), (-1, -1), 0) ts.add("RIGHTPADDING", (0, 0), (-1, -1), 0) # This is the header row ts.add('LINEBELOW', (0, 0), (0, 0), 0.5, colors.black) ts.add('LINEBELOW', (2, 0), (2, 0), 0.5, colors.black) ts.add('LINEBELOW', (4, 0), (4, 0), 0.5, colors.black) ts.add('LINEBELOW', (6, 0), (6, 0), 0.5, colors.black) ts.add('LINEBELOW', (8, 0), (8, 0), 0.5, colors.black) ts.add('LINEBELOW', (10, 0), (10, 0), 0.5, colors.black) #ts.add('LINEBELOW', (6, -2), (6, -2), 0.5, colors.black) # subtotal line ts.add('VALIGN', (0, 0), (-1, 0), 'MIDDLE') # for row in titles_row: # ts.add('FONT', (0, row), (-1, row), 'Helvetica', 10) t.setStyle(ts) complete_document.append(t) footer = preorder.preorder_print_note_footer or "" p = Paragraph(escape_html(footer),s) complete_document.append(p) # complete_document.append(spacer) # p = Paragraph(_("This is a preorder."),s) # complete_document.append(p) data_ops = [ [ "", Paragraph(_("Signature"),s)] ] t = platypus.Table(data_ops, repeatRows=1, colWidths=[8*cm,8*cm]) # Repeat the table header complete_document.append(t) append_general_conditions(complete_document) ladderDoc = customer_PDF(filename) ladderDoc.subject = date_to_dmy(datetime.today(),full_month=True) # or preorder.creation_date ? ladderDoc.build(complete_document,canvasmaker=NumberedCanvas)
def pisaLoop(node, context, path=None, **kw): if path is None: path = [] # Initialize KW if not kw: kw = { "margin-top": 0, "margin-bottom": 0, "margin-left": 0, "margin-right": 0, } else: kw = copy.copy(kw) #indent = len(path) * " " # only used for debug print statements # TEXT if node.nodeType == Node.TEXT_NODE: # print indent, "#", repr(node.data) #, context.frag context.addFrag(node.data) # context.text.append(node.value) # ELEMENT elif node.nodeType == Node.ELEMENT_NODE: node.tagName = node.tagName.replace(":", "").lower() if node.tagName in ("style", "script"): return path = copy.copy(path) + [node.tagName] # Prepare attributes attr = pisaGetAttributes(context, node.tagName, node.attributes) #log.debug(indent + "<%s %s>" % (node.tagName, attr) + repr(node.attributes.items())) #, path # Calculate styles context.cssAttr = CSSCollect(node, context) context.node = node # Block? PAGE_BREAK = 1 PAGE_BREAK_RIGHT = 2 PAGE_BREAK_LEFT = 3 pageBreakAfter = False frameBreakAfter = False display = context.cssAttr.get("display", "inline").lower() # print indent, node.tagName, display, context.cssAttr.get("background-color", None), attr isBlock = (display == "block") if isBlock: context.addPara() # Page break by CSS if "-pdf-next-page" in context.cssAttr: context.addStory( NextPageTemplate(str(context.cssAttr["-pdf-next-page"]))) if "-pdf-page-break" in context.cssAttr: if str(context.cssAttr["-pdf-page-break"]).lower() == "before": context.addStory(PageBreak()) if "-pdf-frame-break" in context.cssAttr: if str(context.cssAttr["-pdf-frame-break"]).lower( ) == "before": context.addStory(FrameBreak()) if str(context.cssAttr["-pdf-frame-break"]).lower() == "after": frameBreakAfter = True if "page-break-before" in context.cssAttr: if str(context.cssAttr["page-break-before"]).lower( ) == "always": context.addStory(PageBreak()) if str(context.cssAttr["page-break-before"]).lower( ) == "right": context.addStory(PageBreak()) context.addStory(PmlRightPageBreak()) if str(context.cssAttr["page-break-before"]).lower() == "left": context.addStory(PageBreak()) context.addStory(PmlLeftPageBreak()) if "page-break-after" in context.cssAttr: if str(context.cssAttr["page-break-after"]).lower( ) == "always": pageBreakAfter = PAGE_BREAK if str(context.cssAttr["page-break-after"]).lower() == "right": pageBreakAfter = PAGE_BREAK_RIGHT if str(context.cssAttr["page-break-after"]).lower() == "left": pageBreakAfter = PAGE_BREAK_LEFT if display == "none": # print "none!" return # Translate CSS to frags # Save previous frag styles context.pushFrag() # Map styles to Reportlab fragment properties CSS2Frag(context, kw, isBlock) # EXTRAS if "-pdf-keep-with-next" in context.cssAttr: context.frag.keepWithNext = getBool( context.cssAttr["-pdf-keep-with-next"]) if "-pdf-outline" in context.cssAttr: context.frag.outline = getBool(context.cssAttr["-pdf-outline"]) if "-pdf-outline-level" in context.cssAttr: context.frag.outlineLevel = int( context.cssAttr["-pdf-outline-level"]) if "-pdf-outline-open" in context.cssAttr: context.frag.outlineOpen = getBool( context.cssAttr["-pdf-outline-open"]) if "-pdf-word-wrap" in context.cssAttr: context.frag.wordWrap = context.cssAttr["-pdf-word-wrap"] # handle keep-in-frame keepInFrameMode = None keepInFrameMaxWidth = 0 keepInFrameMaxHeight = 0 if "-pdf-keep-in-frame-mode" in context.cssAttr: value = str( context.cssAttr["-pdf-keep-in-frame-mode"]).strip().lower() if value in ("shrink", "error", "overflow", "truncate"): keepInFrameMode = value if "-pdf-keep-in-frame-max-width" in context.cssAttr: keepInFrameMaxWidth = getSize("".join( context.cssAttr["-pdf-keep-in-frame-max-width"])) if "-pdf-keep-in-frame-max-height" in context.cssAttr: keepInFrameMaxHeight = getSize("".join( context.cssAttr["-pdf-keep-in-frame-max-height"])) # ignore nested keep-in-frames, tables have their own KIF handling keepInFrame = keepInFrameMode is not None and context.keepInFrameIndex is None if keepInFrame: # keep track of current story index, so we can wrap everythink # added after this point in a KeepInFrame context.keepInFrameIndex = len(context.story) # BEGIN tag klass = globals().get( "pisaTag%s" % node.tagName.replace(":", "").upper(), None) obj = None # Static block elementId = attr.get("id", None) staticFrame = context.frameStatic.get(elementId, None) if staticFrame: context.frag.insideStaticFrame += 1 oldStory = context.swapStory() # Tag specific operations if klass is not None: obj = klass(node, attr) obj.start(context) # Visit child nodes context.fragBlock = fragBlock = copy.copy(context.frag) for nnode in node.childNodes: pisaLoop(nnode, context, path, **kw) context.fragBlock = fragBlock # END tag if obj: obj.end(context) # Block? if isBlock: context.addPara() # XXX Buggy! # Page break by CSS if pageBreakAfter: context.addStory(PageBreak()) if pageBreakAfter == PAGE_BREAK_RIGHT: context.addStory(PmlRightPageBreak()) if pageBreakAfter == PAGE_BREAK_LEFT: context.addStory(PmlLeftPageBreak()) if frameBreakAfter: context.addStory(FrameBreak()) if keepInFrame: # get all content added after start of -pdf-keep-in-frame and wrap # it in a KeepInFrame substory = context.story[context.keepInFrameIndex:] context.story = context.story[:context.keepInFrameIndex] context.story.append( KeepInFrame(content=substory, maxWidth=keepInFrameMaxWidth, maxHeight=keepInFrameMaxHeight)) context.keepInFrameIndex = None # Static block, END if staticFrame: context.addPara() for frame in staticFrame: frame.pisaStaticStory = context.story context.swapStory(oldStory) context.frag.insideStaticFrame -= 1 # context.debug(1, indent, "</%s>" % (node.tagName)) # Reset frag style context.pullFrag() # Unknown or not handled else: # context.debug(1, indent, "???", node, node.nodeType, repr(node)) # Loop over children for node in node.childNodes: pisaLoop(node, context, path, **kw)
def fbreak(story=story): story.append(FrameBreak())
def start(self, c): c.addPara() c.addStory(FrameBreak())
def test0(self): "IndentTestCase test0" if rl_invariant: random.seed(1479316371) # Build story. story = [] doc = MyDocTemplate(outputfile('test_platypus_indents.pdf')) storyAdd = story.append styleSheet = getSampleStyleSheet() h1 = styleSheet['Heading1'] h1.spaceBefore = 18 bt = styleSheet['BodyText'] bt.spaceBefore = 6 storyAdd(Paragraph('Test of context-relative indentation', h1)) storyAdd(Spacer(18, 18)) storyAdd(Indenter(0, 0)) storyAdd( Paragraph( "This should be indented 0 points at each edge. " + ("spam " * 25), bt)) storyAdd(Indenter(0, 0)) storyAdd(Indenter(36, 0)) storyAdd( Paragraph( "This should be indented 36 points at the left. " + ("spam " * 25), bt)) storyAdd(Indenter(-36, 0)) storyAdd(Indenter(0, 36)) storyAdd( Paragraph( "This should be indented 36 points at the right. " + ("spam " * 25), bt)) storyAdd(Indenter(0, -36)) storyAdd(Indenter(36, 36)) storyAdd( Paragraph( "This should be indented 36 points at each edge. " + ("spam " * 25), bt)) storyAdd(Indenter(36, 36)) storyAdd( Paragraph( "This should be indented a FURTHER 36 points at each edge. " + ("spam " * 25), bt)) storyAdd(Indenter(-72, -72)) storyAdd( Paragraph( "This should be back to normal at each edge. " + ("spam " * 25), bt)) storyAdd(Indenter(36, 36)) storyAdd( Paragraph(("""This should be indented 36 points at the left and right. It should run over more than one page and the indent should continue on the next page. """ + (random.randint(0, 10) * 'x') + ' ') * 20, bt)) storyAdd(Indenter(-36, -36)) storyAdd(NextPageTemplate('updown')) storyAdd(FrameBreak()) storyAdd(Paragraph('Another test of context-relative indentation', h1)) storyAdd(NextPageTemplate( 'normal')) # so NEXT page is different template... storyAdd( Paragraph( """This time we see if the indent level is continued across frames...this page has 2 frames, let's see if it carries top to bottom. Then onto a totally different template.""", bt)) storyAdd(Indenter(0, 0)) storyAdd( Paragraph( "This should be indented 0 points at each edge. " + ("spam " * 25), bt)) storyAdd(Indenter(0, 0)) storyAdd(Indenter(36, 72)) storyAdd( Paragraph(("""This should be indented 36 points at the left and 72 at the right. It should run over more than one frame and one page, and the indent should continue on the next page. """ + (random.randint(0, 10) * 'x') + ' ') * 35, bt)) storyAdd(Indenter(-36, -72)) storyAdd( Paragraph( "This should be back to normal at each edge. " + ("spam " * 25), bt)) storyAdd(PageBreak()) storyAdd(PageBreak()) storyAdd( Paragraph( "Below we should colour the background lightgreen and have a red border", bt)) storyAdd( FrameBG(start=True, color=lightgreen, strokeColor=toColor('red'), strokeWidth=1)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Spacer(6, 6)) storyAdd(FrameBG(start=False)) storyAdd( Paragraph("Below we should colour the background lightgreen", bt)) storyAdd( FrameBG(start=True, color=lightgreen, strokeColor=toColor('red'), strokeWidth=None)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(Spacer(6, 6)) storyAdd(FrameBG(start=False)) storyAdd( Paragraph( "Below we split to two new frames with dark green borders", bt)) storyAdd(FrameSplitter('templateX', ['XF4', 'XF5'], adjustHeight=False)) storyAdd( FrameBG(start=True, color=lightgreen, strokeColor=toColor('red'), strokeWidth=1)) for i in xrange(15): storyAdd( Paragraph( "We should have a light green background here %d" % i, bt)) storyAdd(Spacer(6, 6)) storyAdd(FrameBG(start=False)) storyAdd(NextPageTemplate('normal')) storyAdd(PageBreak()) storyAdd( Paragraph("Below we should colour the background lightgreen", bt)) storyAdd(FrameBG(start="frame", color=lightgreen)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(PageBreak()) storyAdd(Paragraph("Here we should have no background.", bt)) storyAdd(PageBreak()) storyAdd(FrameBG(start="frame", color=lightblue)) storyAdd( Paragraph( "We should have a light blue background here and the whole frame should be filled in.", bt)) storyAdd(PageBreak()) storyAdd(Paragraph("Here we should have no background again.", bt)) storyAdd( Paragraph("Below we should colour the background lightgreen", bt)) storyAdd(FrameBG(start="frame-permanent", color=lightgreen)) storyAdd(Paragraph("We should have a light green background here", bt)) storyAdd(PageBreak()) storyAdd( Paragraph("Here we should still have a lightgreen background.", bt)) storyAdd(PageBreak()) storyAdd(FrameBG(start="frame", color=lightblue, left=36, right=36)) storyAdd( Paragraph("We should have a lighgreen/lightblue background.", bt)) storyAdd(PageBreak()) storyAdd( Paragraph("Here we should have only light green background.", bt)) doc.multiBuild(story)
def test0(self): "This makes one long multi-page paragraph." # Build story. story = [] styleSheet = getSampleStyleSheet() h1 = styleSheet['Heading1'] h1.spaceBefore = 18 bt = styleSheet['BodyText'] bt.spaceBefore = 6 story.append(Paragraph('Test of context-relative indentation', h1)) story.append(Spacer(18, 18)) story.append(Indenter(0, 0)) story.append( Paragraph( "This should be indented 0 points at each edge. " + ("spam " * 25), bt)) story.append(Indenter(0, 0)) story.append(Indenter(36, 0)) story.append( Paragraph( "This should be indented 36 points at the left. " + ("spam " * 25), bt)) story.append(Indenter(-36, 0)) story.append(Indenter(0, 36)) story.append( Paragraph( "This should be indented 36 points at the right. " + ("spam " * 25), bt)) story.append(Indenter(0, -36)) story.append(Indenter(36, 36)) story.append( Paragraph( "This should be indented 36 points at each edge. " + ("spam " * 25), bt)) story.append(Indenter(36, 36)) story.append( Paragraph( "This should be indented a FURTHER 36 points at each edge. " + ("spam " * 25), bt)) story.append(Indenter(-72, -72)) story.append( Paragraph( "This should be back to normal at each edge. " + ("spam " * 25), bt)) story.append(Indenter(36, 36)) story.append( Paragraph(("""This should be indented 36 points at the left and right. It should run over more than one page and the indent should continue on the next page. """ + (random.randint(0, 10) * 'x') + ' ') * 20, bt)) story.append(Indenter(-36, -36)) story.append(NextPageTemplate('updown')) story.append(FrameBreak()) story.append( Paragraph('Another test of context-relative indentation', h1)) story.append(NextPageTemplate( 'normal')) # so NEXT page is different template... story.append( Paragraph( """This time we see if the indent level is continued across frames...this page has 2 frames, let's see if it carries top to bottom. Then onto a totally different template.""", bt)) story.append(Indenter(0, 0)) story.append( Paragraph( "This should be indented 0 points at each edge. " + ("spam " * 25), bt)) story.append(Indenter(0, 0)) story.append(Indenter(36, 72)) story.append( Paragraph(("""This should be indented 36 points at the left and 72 at the right. It should run over more than one frame and one page, and the indent should continue on the next page. """ + (random.randint(0, 10) * 'x') + ' ') * 35, bt)) story.append(Indenter(-36, -72)) story.append( Paragraph( "This should be back to normal at each edge. " + ("spam " * 25), bt)) doc = MyDocTemplate(outputfile('test_platypus_indents.pdf')) doc.multiBuild(story)
def start(self, c): c.add_paragraph() c.add_story(FrameBreak())
def build(self, studentEvaluations): doc = ShanghaiMovementCheck2015DocTemplate(self.filename) Story = [] styles = self.styles fig = plt.figure(figsize=(14, 3.5)) for studentEvaluation in studentEvaluations: if studentEvaluation.testPlan is not None: testPlanName = studentEvaluation.testPlan.name else: testPlanName = '运动能力测试' Story.append(FrameBreak('Header')) Story.append(Paragraph('证书', self.styles['Title'])) Story.append(Paragraph(testPlanName, self.styles['Subtitle'])) Story.append(FrameBreak('Content')) pdfStudentBasicInfo = PdfStudentBasicInfo(studentEvaluation, style=styles['Normal']) Story.append(pdfStudentBasicInfo) Story.append(Spacer(0, 0.25 * cm)) p = Paragraph('您在%s中的表现' % testPlanName, styles['Normal']) Story.append(p) Story.append(Spacer(0, 0.25 * cm)) pdfStudentPRChart = get_studentPRChart( studentEvaluation, showPercentValue=self.isAdmin) Story.append(pdfStudentPRChart) Story.append(Spacer(0, 0.5 * cm)) p = Paragraph( '50%表示同年龄段孩子所具备运动能力的平均水平,百分比值越高代表孩子具备的运动能力越突出。百分比只是运动能力的参考值。', styles['Normal']) Story.append(p) normChart = _gen_norm_chart(studentEvaluation, fig) Story.append(normChart) Story.append(Spacer(0, 0.25 * cm)) p = Paragraph( '尊敬的家长:<br/>感谢您的孩子参加了我们的运动能力测试!<br/>您的孩子正处于各项身体素质发展的关键敏感期。这个阶段也是传统意义上的儿童体育运动阶段。让孩子参加到各种儿童体育运动中去,将为孩子运动机能的全面发展提供重要的机会。跳、跑、踢、抛、接、滑动、转动等能力,如果得到综合的运用和锻炼,将使孩子的手、眼、脑、四肢、肌肉、神经、心理得到均衡发展,并使您的孩子茁壮成长。', styles['Normal']) Story.append(p) Story.append(Spacer(0, 0.25 * cm)) #只有在测试数据完整时才做出评价 if studentEvaluation.studentDataComplete: pdfStudentComment = PdfStudentComment(studentEvaluation, style=styles['Normal']) Story.append(pdfStudentComment) Story.append(FrameBreak('Signature')) p = Paragraph( '''上海市青少年体育选材育才中心 Shanghai Sports Talent Identification & Development Center<br/>德国拜罗伊特大学 University of Bayreuth - Training & Movement Science''', styles['Normal']) Story.append(p) Story.append(PageBreak()) doc.build(Story)
def frameAction(self, frame): if self.style.float not in ('left', 'right'): return if frame.onSidebar: # We are still on the frame next to a sidebar! frame._generated_content = [FrameBreak(), self] else: w = frame.container.styles.adjustUnits(self.width, frame.width) idx = frame.container.frames.index(frame) padding = self.style.borderPadding width = self.style.width self.style.padding = frame.container.styles.adjustUnits( str(padding), frame.width ) self.style.width = frame.container.styles.adjustUnits( str(width), frame.width ) self.kif = BoxedContainer(self.flowables, self.style) if self.style.float == 'left': self.style.lpad = frame.leftPadding f1 = SmartFrame( frame.container, frame._x1, frame._y1p, w - 2 * self.style.padding, frame._y - frame._y1p, leftPadding=self.style.lpad, rightPadding=0, bottomPadding=0, topPadding=0, ) f1._atTop = frame._atTop frame.container.frames.insert(idx + 1, f1) frame._generated_content = [ FrameBreak(), self.kif, FrameCutter( w, frame.width - w, self.kif, padding, self.style.lpad, True, ), FrameBreak(), ] elif self.style.float == 'right': self.style.lpad = frame.rightPadding frame.container.frames.insert( idx + 1, SmartFrame( frame.container, frame._x1 + frame.width - self.style.width, frame._y1p, w, frame._y - frame._y1p, rightPadding=self.style.lpad, leftPadding=0, bottomPadding=0, topPadding=0, ), ) frame._generated_content = [ FrameBreak(), self.kif, FrameCutter( w, frame.width - w, self.kif, padding, self.style.lpad, False, ), FrameBreak(), ]
def next_frame(self): self.complete_document.append(FrameBreak())
def _make_supply_order(supply_order_id,filename): global header_text global sub_header_text s = ParagraphStyle(name = "regular", fontName = 'Helvetica', fontSize=12, spaceAfter=6) table_style = ParagraphStyle(name = "regular", fontName = 'Helvetica', fontSize=11, spaceAfter=6) signatures_style = ParagraphStyle(name = "signature", fontName = 'Helvetica', fontSize=12, alignment=TA_CENTER) warning_style = ParagraphStyle(name = "warning", fontName = 'Helvetica-Bold', fontSize=20, spaceAfter=6,alignment=TA_CENTER, borderWidth=2, borderColor=colors.black, leading=30) right_align = ParagraphStyle(name = "right_align", fontName = 'Helvetica', fontSize=12,alignment=TA_RIGHT) complete_document = [] spacer = platypus.Spacer(1,1*cm) supply_order, parts = supply_order_service.find_by_id(supply_order_id) supplier = supplier_service.find_by_id(supply_order.supplier_id) p = Paragraph(escape_html(supplier.fullname),s) complete_document.append(p) p = Paragraph(escape_html(supplier.address1),s) complete_document.append(p) p = Paragraph(escape_html(supplier.address2),s) complete_document.append(p) complete_document.append(FrameBreak()) append_header_block(complete_document, _("Order number <b>{}</b>, your ref. : {}").format(supply_order.accounting_label, escape_html(supply_order.supplier_reference or '-')), supply_order.creation_date) p = Paragraph(escape_html(_("Delivery date : {}").format(date_to_dmy(supply_order.expected_delivery_date))),s) complete_document.append(p) # Well, by combining a MIDDLE VALIGN and a leading=20, I can get the # paragraph to be right in the middle of the cell (vertically speaking) # It doesn't make sense to me, it's pure trial and error... subtitle = ParagraphStyle(name = "subtitle", fontName = 'Helvetica', fontSize=16, leading=20) p = Paragraph("",s) complete_document.append(p) complete_document.append(spacer) data_ops = [ [ _('Ref.'),'',_('Description'),'',_('Quantity'),'',_('Unit price') ] ] for part in parts: data_ops.append([Paragraph(escape_html(part.human_identifier),table_style), None, Paragraph(escape_html(part.description),table_style), None, Paragraph(u"{}".format(quantity_to_str(part.quantity)),table_style), None, Paragraph(u"{}".format(amount_to_s(part.unit_price,"-")),table_style)]) t = platypus.Table(data_ops, repeatRows=1, colWidths=[1.25*cm,0.75*cm,10*cm,0.75*cm,2*cm,0.75*cm,2.5*cm]) # Repeat the table header ts = platypus.TableStyle([('FONT', (0, 0), (-1, -1), 'Helvetica-Bold', 12)]) ts.add('ALIGN', (0, 0), (-1, -1), 'LEFT') ts.add('VALIGN', (0, 0), (-1, -1), 'TOP') ts.add("LEFTPADDING", (0, 0), (-1, -1), 0) ts.add("RIGHTPADDING", (0, 0), (-1, -1), 0) # This is the header row ts.add('LINEBELOW', (0, 0), (0, 0), 0.5, colors.black) ts.add('LINEBELOW', (2, 0), (2, 0), 0.5, colors.black) ts.add('LINEBELOW', (4, 0), (4, 0), 0.5, colors.black) ts.add('LINEBELOW', (6, 0), (6, 0), 0.5, colors.black) ts.add('VALIGN', (0, 0), (-1, 0), 'MIDDLE') # for row in titles_row: # ts.add('FONT', (0, row), (-1, row), 'Helvetica', 10) t.setStyle(ts) complete_document.append(t) complete_document.append(spacer) data_ops = [ [ Paragraph(_("Daniel Dumont<br/>Administrateur delegue"),signatures_style), Paragraph(_("Pierre Jodogne<br/>Superviseur de production"),signatures_style)] ] t = platypus.Table(data_ops, repeatRows=1, colWidths=[9*cm,9*cm]) # Repeat the table header ts = platypus.TableStyle([('FONT', (0, 0), (-1, -1), 'Helvetica-Bold', 12)]) ts.add('ALIGN', (0, 0), (-1, -1), 'CENTER') t.setStyle(ts) complete_document.append(t) ladderDoc = customer_PDF(filename) ladderDoc.build(complete_document,canvasmaker=NumberedCanvas)