def docTemplate(docname): doc = BaseDocTemplate( files, topMargin=95, bottomMargin=25, leftMargin=5, rightMargin=10 ) # pagesize=A4) #landscape(A4) para Horizontal #,showBoundary=1 recuadro de las paginas #CREAMOS LOS FRAMES frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='col1') #CREAMOS LOS PAGETEMPLATE doc.addPageTemplates([ PageTemplate(id='contenido', frames=frame, onPage=Header, onPageEnd=Footer) ]) return doc
def build_pdf(filename, flowables): doc = BaseDocTemplate(filename) doc.addPageTemplates( [ PageTemplate( frames=[ Frame( doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id=None ), ] ), ] ) doc.build(flowables)
def create_report(self, buff=None): def get_method(section): try: method = getattr(self, "_section_" + section) except AttributeError: raise Exception("Section method not found: " + section) return method if not buff: buff = io.BytesIO() story = [] for section in self.sections: elems = get_method(section)() for elem in elems: story.append(elem) page_t = PageTemplate('normal', [ Frame( self.page_margin[0], self.page_margin[1], self.page_size[0] - self.page_margin[0] * 2, self.page_size[1] - self.page_margin[1] * 2, leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, ) ]) doc_t = BaseDocTemplate( buff, pagesize=letter, title=self.title, author=self.author, leftMargin=self.page_margin[0], rightMargin=self.page_margin[0], topMargin=self.page_margin[1], bottomMargin=self.page_margin[1], ) doc_t.addPageTemplates(page_t) doc_t.build(story) buff.seek(0) return buff
def build_pdf(data, logo_path=None, watermark=None, images_data=None): global WATERMARK global LOGO_PATH global BODY_STYLE LOGO_PATH = logo_path WATERMARK = watermark BODY_STYLE = get_body_style() pdf_buffer = BytesIO() pdf = BaseDocTemplate(pdf_buffer, pagesize=A4) frame = Frame(LEFT_MARGIN, BOTTOM_MARGIN, PAGE_WIDTH, 687, showBoundary=1) template = PageTemplate(id='all_pages', frames=frame, onPage=header_and_footer) pdf.addPageTemplates([template]) images_before_table = [] images_after_table = [] for img_path, img_pos in images_data.items(): if img_pos == IMAGE_DOC_POSITION_BEFORE_TABLE: images_before_table.append(img_path) elif img_pos == IMAGE_DOC_POSITION_AFTER_TABLE: images_after_table.append(img_path) story = [] for img_path in images_before_table: story.extend([ Spacer(10, 10), Image(img_path, width=100, height=100), Spacer(10, 10) ]) story.append(pfd_table_builder(data)) for img_path in images_after_table: story.extend([ Spacer(10, 10), Image(img_path, width=100, height=100), Spacer(10, 10) ]) pdf.build(story) pdf_value = pdf_buffer.getvalue() pdf_buffer.close() return pdf_value
def _create_pdf(invoice_buffer, sanction_outcome): every_page_frame = Frame( PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame', ) # showBoundary=Color(0, 1, 0)) every_page_frame2 = Frame( PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame2', ) # showBoundary=Color(0, 0, 1)) every_page_template = PageTemplate( id='EveryPages', frames=[ every_page_frame, ], ) every_page_template2 = PageTemplate( id='EveryPages2', frames=[ every_page_frame2, ], ) doc = BaseDocTemplate( invoice_buffer, pageTemplates=[ every_page_template, every_page_template2, ], pagesize=A4, ) # showBoundary=Color(1, 0, 0)) t1 = get_infringement_notice_table(sanction_outcome) elements = [] elements.append(t1) elements.append(PageBreak()) doc.build(elements) return invoice_buffer
def _create_bulk_licence_renewal(licences, site_url, buf=None): bulk_licence_renewal_frame = Frame(LETTER_PAGE_MARGIN, LETTER_PAGE_MARGIN, PAGE_WIDTH - 2 * LETTER_PAGE_MARGIN, PAGE_HEIGHT - 160, id='BulkLicenceRenewalFrame') bulk_licence_renewal_template = PageTemplate(id='BulkLicenceRenewalFrame', frames=[bulk_licence_renewal_frame], onPage=_create_letter_header_footer) if buf is None: buf = BytesIO() doc = BaseDocTemplate(buf, pageTemplates=[bulk_licence_renewal_template], pagesize=A4) # this is the only way to get data into the onPage callback function doc.site_url = site_url all_elements = [] for licence in licences: all_elements += _create_letter_address(licence) + [Spacer(1, LETTER_ADDRESS_BUFFER_HEIGHT)] + \ _create_licence_renewal_elements(licence) + _create_letter_signature() all_elements.append(PageBreak()) doc.build(all_elements) return doc
def get(self, request, *args, **kwargs): if not self.get_queryset().exists(): messages.warning(request, _('You don\'t have any submissions yet.')) return redirect(request.event.orga_urls.submissions) with tempfile.NamedTemporaryFile(suffix=".pdf") as f: doc = BaseDocTemplate(f.name, pagesize=A4, leftMargin=0, rightMargin=0, topMargin=0, bottomMargin=0) doc.addPageTemplates([ PageTemplate(id='All', frames=[ Frame(0, 0, doc.width / 2, doc.height, leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, id='left'), Frame(doc.width / 2, 0, doc.width / 2, doc.height, leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, id='right') ], pagesize=A4) ]) doc.build(self.get_story(doc)) f.seek(0) r = HttpResponse(content_type='application/pdf') timestamp = now().strftime('%Y-%m-%d-%H%M') r['Content-Disposition'] = f'attachment; filename="{request.event.slug}_submission_cards_{timestamp}.pdf"' r.write(f.read()) return r
def __init__(self,doc): self.docname = doc self.page_counter = 2 self.w,self.h = letter self.doc = BaseDocTemplate(self.docname,pagesize=letter) self.landscape = Frame(self.doc.leftMargin, self.doc.bottomMargin, self.doc.height, self.doc.width, id="Normal") self.portrait = Frame(self.doc.leftMargin, self.doc.bottomMargin, self.doc.width, self.doc.height, id="Normal") self.tportrait = Frame(self.doc.leftMargin, self.doc.bottomMargin, self.doc.width, self.doc.height, id="Normal") ttemplate = PageTemplate(id='tportrait',frames =self.tportrait, onPage=self.make_title_page) ptemplate = PageTemplate(id='portrait',frames =self.portrait, onPage=self.make_portrait) ltemplate = PageTemplate(id='landscape',frames =self.landscape, onPage=self.make_landscape) self.doc.addPageTemplates([ttemplate,ptemplate,ltemplate]) self.styles = getSampleStyleSheet() self.toc = TableOfContents() self.start = "" self.end = "" self.story = [] self.pgType = "Letter" self.image = "" self.cimage = "" self.client = "" self.toc = TableOfContents() self.toc.levelStyles = [ PS(fontName='Times-Bold', fontSize=14, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10, leading=16), PS(fontSize=12, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12), ]
def qrcodes(request): doc = BaseDocTemplate('temp.pdf', title='users') elements = [] pdfmetrics.registerFont(TTFont('ProximaNova', 'ProximaNova-Regular.ttf')) style = getSampleStyleSheet()['Normal'] style.alignment = 1 style.fontName = 'ProximaNova' elements.append(NextPageTemplate('Def')) for user in User.objects.filter(Q(groups__name=app_name)): if not user.is_superuser: out = {'key': user.username, 'univ': app_name} img = QrCode(json.dumps(out), width=50 * mm, height=50 * mm) img.hAlign = 'CENTER' string = '''Key: {}<br/> Univer: {}<br/> {} {}''' if user.first_name + user.last_name: string = string.format( user.username, app_name, user.first_name + ' ' + user.last_name + '<br/>', '{}') else: string = string.format(user.username, app_name, '', '{}<br/>') string = string.format('Секретарь') if user.groups.filter( name='secretaries') else string.format('<br/>') p = Paragraph('<para align=center>' + string + '</para>', style) elements.append(KeepTogether([img, p])) elements.append(Spacer(5 * mm, 5 * mm)) frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width / 2 - 6, doc.height) frame2 = Frame(doc.leftMargin + doc.width / 2 + 6, doc.bottomMargin, doc.width / 2 - 6, doc.height) doc.addPageTemplates([PageTemplate(id='Def', frames=[frame1, frame2])]) doc.build(elements) response = FileResponse(open('temp.pdf', 'rb'), as_attachment=False) response['Content-Disposition'] = 'inline; filename="users.pdf"' return response
def generar_pdf(titulo, elementsFilaPage): response = HttpResponse(content_type='application/pdf') buff = BytesIO() doc = BaseDocTemplate(buff, pagesize=landscape(A4), title=titulo) doc.addPageTemplates([ PageTemplate(id='cabecera', frames=Frame(inch/3, inch/3, 800, 560, id='normal', showBoundary=0), onPage=__encabezado_A4_Horizontal), ] ) story = [] styles = getSampleStyleSheet() story.append(Spacer(0, 150)) for i in elementsFilaPage: story.append(i) doc.build(story) response.write(buff.getvalue()) buff.close() return response
def create_report_for_statistics(working_dir): doc = BaseDocTemplate( "report1.pdf", pagesize=A4, rightMargin=72, leftMargin=72, topMargin=50, bottomMargin=80, showBoundary=False) styles = getSampleStyleSheet() frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 2 * cm, id='normal') elements = sms_statistics_part(working_dir) elements.extend(calllog_statistics(working_dir)) template = PageTemplate(id='statistics', frames=frame) doc.addPageTemplates([template]) doc.build(elements)
def _create_licence_renewal(licence_renewal_buffer, licence, site_url): licence_renewal_frame = Frame(LETTER_PAGE_MARGIN, LETTER_PAGE_MARGIN, PAGE_WIDTH - 2 * LETTER_PAGE_MARGIN, PAGE_HEIGHT - 160, id='LicenceRenewalFrame') licence_renewal_template = PageTemplate( id='LicenceRenewalFrame', frames=licence_renewal_frame, onPage=_create_letter_header_footer) doc = BaseDocTemplate(licence_renewal_buffer, pageTemplates=[licence_renewal_template], pagesize=A4) elements = _create_letter_address(licence) + [Spacer(1, LETTER_ADDRESS_BUFFER_HEIGHT)] + \ _create_licence_renewal_elements(licence) + _create_letter_signature() doc.build(elements) return licence_renewal_buffer
def __init__(self, fname="report.pdf", dwidth=250 * mm, dheight=150 * mm, dpads=0 * mm, show_bound=0): self.fname = fname self.dwidth = dwidth self.dheight = dheight self.dpads = dpads self.show_bound = show_bound self.doc = BaseDocTemplate(fname, pagesize=(dwidth, dheight), rightMargin=dpads, leftMargin=dpads, topMargin=dpads, bottomMargin=dpads) # default frame size self.default_fwidth = (self.doc.width - ((3 - 1) * self.dpads)) / 3 self.default_fheight = (self.doc.height - ((2 - 1) * self.dpads)) / 2
def create(self): from reportlab.platypus import BaseDocTemplate, PageTemplate from reportlab.lib.units import mm with tempfile.NamedTemporaryFile(suffix=".pdf") as f: Report.register_fonts() doc = BaseDocTemplate(f.name, pagesize=self.pagesize, leftMargin=15 * mm, rightMargin=15 * mm, topMargin=20 * mm, bottomMargin=15 * mm) doc.addPageTemplates([ PageTemplate(id='All', frames=self.get_frames(doc), onPage=self.on_page, pagesize=self.pagesize) ]) doc.build(self.get_story(doc)) f.seek(0) return f.read()
def generate(self): # self._doc = SimpleDocTemplate( # self._filename, pagesize=letter) self._doc = BaseDocTemplate(self._filename, pagesize=letter) page_width, page_height = letter self._frame = Frame(self._doc.leftMargin, self._doc.bottomMargin, self._doc.width, self._doc.height, leftPadding=10, rightPadding=10, showBoundary=0) self._doc.addPageTemplates([ PageTemplate(id='Col', onPage=self._add_page_number, frames=[self._frame]), ]) self._story.append(self._render_header()) self._story.append(Spacer(page_width, 30)) if hasattr( self._data, 'recurring_charges') and self._data.recurring_charges: ###### self._story.append(self._render_summary()) if hasattr(self._data, 'transaction_summary') and len( self._data.transaction_summary): self._story.append( KeepTogether(self._render_transaction_summary_analysis())) # if self._data['show_authorization_code_summary']: # self._story.append(KeepTogether(self._render_authorization_code_summary_report())) # if self._data['show_all_area_codes_summary']: # self._story.append(KeepTogether(self._render_all_area_codes_summary_report())) # if self._data['show_origination_lata_summary']: # self._story.append(KeepTogether(self._render_origination_lata_summary_report())) self._story.append(Spacer(page_width, 30)) self._story.append(self._render_footer()) self._doc.build(self._story) return True
def process_canvas(self, canvas, f): frames = [] colwidth = (self.pagesize[0] \ - (2 * self.margin) \ - ((self.columns - 1) * self.colgap)) / self.columns colheight = self.pagesize[1] \ - (2 * self.margin) colspacing = colwidth + self.colgap for col in range(0, self.columns): frames.append( Frame(self.margin + (colspacing * col), self.margin, colwidth, colheight)) pagetemplate = PageTemplate(id='default', frames=frames) doctemplate = BaseDocTemplate(f, pagesize=self.pagesize, pageTemplates=[pagetemplate], showBoundary=1) story = [] for i in canvas: if hasattr(i, 'left') \ or hasattr(i, 'center') \ or hasattr(i, 'right'): left = getattr(i, 'left', '') center = getattr(i, 'center', '') right = getattr(i, 'right', '') font = self.fontname if getattr(i, 'emph', 0) or getattr(i, 'colour', 0): font += "-Bold" fontsize = self.fontsizes[getattr(i, 'font', 0)] pitch = self.pitches[getattr(i, 'font', 0)] if not center: story.append(LRLine(left, right, font, fontsize, pitch)) elif center: story.append(CenterLine(center, font, fontsize, pitch)) else: pass doctemplate.build(story)
def init_reportlab(self, save_to_file=True): self.styles = getSampleStyleSheet() self.buff = BytesIO() self.doc = BaseDocTemplate(os.path.join(self.output_path, self.filename) if save_to_file else self.buff, pagesize=self.page_format, leftMargin=self.page_margin * cm, rightMargin=self.page_margin * cm, topMargin=self.page_margin * cm, bottomMargin=self.page_margin * cm, showBoundary=0, allowSplitting=1) # define styles for paragraphs self.styles.add(ParagraphStyle( 'Header', fontSize=self.font_size, fontName=self.font_name, spaceBefore=self.space_before, spaceAfter=self.space_after, leading=self.font_size, alignment=TA_CENTER )) self.styles.add(ParagraphStyle( 'Move_Text', fontSize=self.font_size, fontName=self.font_name, spaceBefore=self.space_before, spaceAfter=self.space_after, leading=self.font_size, )) # TODO: Add more Layouts if False: pass elif self.page_layout == 'two_col': frame_width = self.doc.width / 2 - self.col_gap / 2 * cm frame1 = Frame(self.doc.leftMargin, self.doc.bottomMargin, frame_width, self.doc.height, id='col1') frame2 = Frame(self.doc.leftMargin + frame_width + self.col_gap * cm, self.doc.bottomMargin, frame_width, self.doc.height, id='col2') self.doc.addPageTemplates([PageTemplate(id='twoCol', frames=[frame1, frame2])]) # Set board dimensions relative to the two column layout self.board_length = 0.8 * frame_width / cm # in cm self.tile_length = self.board_length / 8 # in cm
def _create_doc(self): doc = BaseDocTemplate( filename=str(self.report_path), pagesize=A4, topMargin=27 * mm, leftMargin=25 * mm, rightMargin=20 * mm, bottomMargin=25 * mm, ) frame = Frame( x1=getattr(doc, "leftMargin"), y1=getattr(doc, "bottomMargin"), width=getattr(doc, "width"), height=getattr(doc, "height"), ) template = PageTemplate( id="report", frames=frame, onPage=self._footer, ) doc.addPageTemplates([template]) return doc
def create_pdfdoc(pdfdoc, story): """ Creates PDF doc from story. """ pdf_doc = BaseDocTemplate(pdfdoc, pagesize=PAGE_SIZE, leftMargin=MARGIN_SIZE, rightMargin=MARGIN_SIZE, topMargin=MARGIN_SIZE, bottomMargin=MARGIN_SIZE) main_frame = Frame(MARGIN_SIZE, MARGIN_SIZE, PAGE_SIZE[0] - 2 * MARGIN_SIZE, PAGE_SIZE[1] - 2 * MARGIN_SIZE, leftPadding=0, rightPadding=0, bottomPadding=0, topPadding=0, id='main_frame') main_template = PageTemplate(id='main_template', frames=[main_frame]) pdf_doc.addPageTemplates([main_template]) pdf_doc.build(story)
def _create_cover_letter(cover_letter_buffer, licence, site_url): cover_letter_frame = Frame(LETTER_PAGE_MARGIN, LETTER_PAGE_MARGIN, PAGE_WIDTH - 2 * LETTER_PAGE_MARGIN, PAGE_HEIGHT - 160, id='CoverLetterFrame') every_cover_letter_template = PageTemplate(id='CoverLetter', frames=[cover_letter_frame], onPage=_create_letter_header_footer) doc = BaseDocTemplate(cover_letter_buffer, pageTemplates=[every_cover_letter_template], pagesize=A4) elements = [] elements += _create_letter_address(licence) elements.append(Spacer(1, LETTER_ADDRESS_BUFFER_HEIGHT)) elements += _create_letter_paragraph('{}'.format(licence.licence_type.name.encode('UTF-8')), style='LetterBoldLeft') elements += _create_letter_paragraph('Please find the licence attached.') elements += _create_letter_paragraph('Please ensure that all the licence conditions are complied with, including ' 'the forwarding of a return at the end of the licence period.') if licence.cover_letter_message: for message in licence.cover_letter_message.split('\r\n'): if message: elements.append(Paragraph(message, styles['LetterLeft'])) else: elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements += _create_letter_paragraph('If you have any queries, please contact the Wildlife Licensing Section ' 'on 9219 9831.') elements += _create_letter_signature() doc.build(elements) return cover_letter_buffer
def _create_application(application_buffer, application): every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame') every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame]) doc = BaseDocTemplate(application_buffer, pageTemplates=[every_page_template], pagesize=A4) elements = [] elements.append( Paragraph(application.licence_type.name.encode('UTF-8'), styles['ApplicationTitle'])) # cannot use licence get_title_with_variants because licence isn't saved yet so can't get variants if application.variants.exists(): variants = '({})'.format(' / '.join( application.variants.all().values_list('name', flat=True))) elements.append(Paragraph(variants, styles['ApplicationVariantsTitle'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(_create_application_metadata(application)) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) for field, datum in zip(application.licence_type.application_schema, application.data): _create_application_questionaire(field, datum, elements, 0) doc.build(elements) return application_buffer
def __init__(self, out_file='out.pdf', pagesize=(80 * mm, 80 * mm)): print('Class AssetTag:init') self.doc = BaseDocTemplate(out_file, showBoundary=0, pagesize=pagesize, leftMargin=0, rightMargin=0, topMargin=0, bottomMargin=0) self.frame_pages = Frame(0, 0, self.doc.width, self.doc.height, id='remaining', leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0) self.doc.addPageTemplates( [PageTemplate(id='table', frames=self.frame_pages)]) self.Elements = [] self.arg_custom_header = None self.arg_data = None self.data = None self.count_of_column = 6 self.colwidth = [self.doc.width / self.count_of_column ] * self.count_of_column # [行1高度,行2高度]+[(文件总高度-前两行高度)/剩余的n行]×n self.count_of_row = 6 # 表格的总行数 self.n = self.count_of_row - 2 self.row_one_height = 15 self.row_two_height = self.doc.height * 0.45 self.rowheight = [ self.row_one_height, self.row_two_height ] + [(self.doc.height - self.row_two_height - self.row_one_height) / self.n] * self.n
def get(self, request, *args, **kwargs): with tempfile.NamedTemporaryFile(suffix=".pdf") as f: doc = BaseDocTemplate(f.name, pagesize=A4, leftMargin=0, rightMargin=0, topMargin=0, bottomMargin=0) doc.addPageTemplates([ PageTemplate(id='All', frames=[ Frame(0, 0, doc.width / 2, doc.height, leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, id='left'), Frame(doc.width / 2, 0, doc.width / 2, doc.height, leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, id='right') ], pagesize=A4) ]) doc.build(self.get_story(doc)) f.seek(0) r = HttpResponse(content_type='application/pdf') r.write(f.read()) return r
def format_wrt(self, output_file, dat): self.logger.debug('dumping contents of dat: {}'.format(repr(dat))) # outline story for document's sake story = self.__outline_story(dat) # setup document template doc = BaseDocTemplate( output_file, pagesize=letter, rightMargin=30, leftMargin=30, topMargin=30, bottomMargin=18, ) def fp_foot(c, d): c.saveState() width, height = letter c.setFont('Helvetica', 7) c.drawCentredString(width / 2.0, (1.00 * cm), dat['FOOTER_ABOUT']) c.restoreState() bill_frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='bill_frame') doc.addPageTemplates([ PageTemplate(id='biil_page', frames=[bill_frame], onPage=fp_foot), ]) # apply story to document doc.build(story, canvasmaker=NumberedCanvas) return
def __init__(self, buffer=None, debug=False): # Buffer must be set! if buffer is None: raise ValueError('Buffer argument is required') else: self.buffer = buffer self.debug = debug # Label parameters are for Avery 6572. # TODO: allow this to be set via options or some other way. # ... a horrible part of me is considering adding a model for label sheets. self.width = 612 self.height = 792 self.top_margin = 36 self.bottom_margin = 36 self.left_margin = 9 self.right_margin = 9 self.rows = 5 self.cols = 3 self.row_gutter = 0 self.col_gutter = 9 # Calculate label width and height. self.labelw = int((self.width - self.left_margin - self.right_margin - (self.cols - 1) * self.col_gutter) / self.cols) self.labelh = int((self.height - self.top_margin - self.bottom_margin - (self.rows - 1) * self.row_gutter) / self.rows) # Get sample style sheet from styles. self.styles = getSampleStyleSheet() self.style = self.styles['Normal'] # Create document from base template. self.doc = BaseDocTemplate(self.buffer, pagesize=(self.width, self.height)) # Construct page template of "frames". Each frame contains one label. self.framelist = [(self.left_margin + y * (self.col_gutter + self.labelw), self.height - self.bottom_margin - self.labelh - x * (self.row_gutter + self.labelh), self.labelw, self.labelh) for x in range(self.rows) for y in range(self.cols)] self.doc.addPageTemplates([PageTemplate(frames=[Frame(a, b, c, d, leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, showBoundary=(1 if self.debug else 0)) for (a, b, c, d) in self.framelist])])
def _create_invoice(invoice_buffer, invoice, proposal): global DPAW_HEADER_LOGO # if cols_var["TEMPLATE_GROUP"] == 'rottnest': # DPAW_HEADER_LOGO = os.path.join(settings.BASE_DIR, 'mooring', 'static', 'mooring', 'img','logo-rottnest-island-sm.png') # else: # DPAW_HEADER_LOGO = os.path.join(settings.BASE_DIR, 'ledger', 'payments','static', 'payments', 'img','dbca_logo.jpg') DPAW_HEADER_LOGO = os.path.join(settings.PROJECT_DIR, 'payments', 'static', 'payments', 'img', 'dbca_logo.jpg') every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN + 250, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 450, id='EveryPagesFrame', showBoundary=0) remit_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 600, id='RemitFrame', showBoundary=0) every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame, remit_frame], onPage=_create_header) doc = BaseDocTemplate(invoice_buffer, pageTemplates=[every_page_template], pagesize=A4) # this is the only way to get data into the onPage callback function doc.invoice = invoice doc.proposal = proposal owner = invoice.owner elements = [] #elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 5)) # Draw Products Table invoice_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 1, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT')]) items = invoice.order.lines.all() discounts = invoice.order.basket_discounts if invoice.text: elements.append(Paragraph(invoice.text, styles['Left'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 2)) data = [['Item', 'Product', 'Quantity', 'Unit Price', 'Total']] val = 1 s = styles["BodyText"] s.wordWrap = 'CJK' for item in items: data.append([ val, Paragraph(item.description, s), item.quantity, currency(item.unit_price_incl_tax), currency(item.line_price_before_discounts_incl_tax) ]) val += 1 # Discounts data.append(['', '', '', '']) for discount in discounts: data.append( ['', discount.offer, '', '', '-${}'.format(discount.amount)]) val += 1 t = Table(data, style=invoice_table_style, hAlign='LEFT', colWidths=( 0.7 * inch, None, 0.7 * inch, 1.0 * inch, 1.0 * inch, )) elements.append(t) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 2)) # /Products Table if invoice.payment_status != 'paid' and invoice.payment_status != 'over_paid': elements.append( Paragraph(settings.INVOICE_UNPAID_WARNING, styles['Left'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 6)) # Remitttance Frame elements.append(FrameBreak()) boundary = BrokenLine(PAGE_WIDTH - 2 * (PAGE_MARGIN * 1.1)) elements.append(boundary) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) remittance = Remittance(HEADER_MARGIN, HEADER_MARGIN - 10, proposal, invoice) elements.append(remittance) #_create_remittance(invoice_buffer,doc) doc.build(elements) return invoice_buffer
def create_annual_rental_fee_awaiting_payment_confirmation( invoice_buffer, annual_rental_fee): global DPAW_HEADER_LOGO DPAW_HEADER_LOGO = os.path.join(settings.PROJECT_DIR, 'payments', 'static', 'payments', 'img', 'dbca_logo.jpg') every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN + 250, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 450, id='EveryPagesFrame', showBoundary=0) remit_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 600, id='RemitFrame', showBoundary=0) every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame, remit_frame], onPage=_create_header) doc = BaseDocTemplate(invoice_buffer, pageTemplates=[every_page_template], pagesize=A4) # this is the only way to get data into the onPage callback function # doc.invoice = invoice # doc.proposal = proposal doc.approval = annual_rental_fee.approval doc.annual_rental_fee = annual_rental_fee # owner = invoice.owner elements = [] #elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 5)) # Draw Products Table invoice_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 1, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT')]) # items = invoice.order.lines.all() items = annual_rental_fee.lines # discounts = invoice.order.basket_discounts # if invoice.text: # elements.append(Paragraph(invoice.text, styles['Left'])) # elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 2)) data = [['Item', 'Product', 'Quantity', 'Unit Price', 'Total']] val = 1 s = styles["BodyText"] s.wordWrap = 'CJK' total_amount = 0.0 # for item in items: for val, item in enumerate(items): amount = float(item['price_incl_tax']) * item['quantity'] data.append([ val, Paragraph(item['ledger_description'], s), item['quantity'], currency(item['price_incl_tax']), currency(amount) ]) total_amount += amount val += 1 data.append(['', 'Total', '', '', currency(total_amount)]) t = Table(data, style=invoice_table_style, hAlign='LEFT', colWidths=( 0.7 * inch, None, 0.7 * inch, 1.0 * inch, 1.0 * inch, )) elements.append(t) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 2)) # /Products Table # if invoice.payment_status != 'paid' and invoice.payment_status != 'over_paid': # elements.append(Paragraph(settings.INVOICE_UNPAID_WARNING, styles['Left'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT * 6)) # Remitttance Frame elements.append(FrameBreak()) boundary = BrokenLine(PAGE_WIDTH - 2 * (PAGE_MARGIN * 1.1)) elements.append(boundary) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # remittance = Remittance(HEADER_MARGIN,HEADER_MARGIN - 10, proposal, invoice) # elements.append(remittance) #_create_remittance(invoice_buffer,doc) doc.build(elements) return invoice_buffer
def _create_pdf(invoice_buffer, sanction_outcome): every_page_frame = Frame( PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame', ) # showBoundary=Color(0, 1, 0)) every_page_frame2 = Frame( PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame2', ) # showBoundary=Color(0, 0, 1)) # every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame,], onPage=_create_header) every_page_template = PageTemplate( id='EveryPages', frames=[ every_page_frame, ], ) every_page_template2 = PageTemplate( id='EveryPages2', frames=[ every_page_frame2, ], ) doc = BaseDocTemplate( invoice_buffer, pageTemplates=[ every_page_template, every_page_template2, ], pagesize=A4, ) # showBoundary=Color(1, 0, 0)) t1 = get_infringement_notice_table(sanction_outcome) data_tbl2 = [] # Notice to alleged offender (1) body = [] body.append( Paragraph( 'It is alleged that you have committed the above offence.</p>', styles['Normal'])) body.append( Paragraph( 'If you do not want to be prosecuted in court for the offence, pay the modified penalty within 28 days after the date of this notice.', styles['Normal'])) body.append(Paragraph('How to pay', styles['Normal'])) body.append( Paragraph( '<strong>By post:</strong>Send a cheque or money order (payable to ‘Approved Officer — Biodiversity Conservation Act 2016’) to:', styles['Normal'])) body.append( Paragraph( 'Approved Officer — Biodiversity Conservation Act 2016<br />Department of Biodiversity, Conservation and Attractions<br />Locked Bag 104<br />Bentley Delivery Centre WA 6983', styles['Normal'])) body.append(Spacer(1, 10)) body.append( Paragraph( '<strong>In person:</strong> Pay the cashier at any office of the Department of Biodiversity, Conservation and Attractions, or pay over the telephone by credit card by calling the general telephone number of any office of the Department of Biodiversity, Conservation and Attractions.', styles['Normal'])) data_tbl2.append([ Paragraph('<strong>Notice to alleged offender</strong>', styles['Normal']), body, '' ]) # Notice to alleged offender (2) body = [] body.append( Paragraph( '<strong>If you do not pay</strong> the modified penalty within 28 days, you may be prosecuted or enforcement action may be taken under the Fines, Penalties and Infringement Notices Enforcement Act 1994. Under that Act, some or all of the following action may be taken — your driver’s licence may be suspended; your vehicle licence may be suspended or cancelled; your details may be published on a website; your vehicle may be immobilised or have its number plates removed; your property may be seized and sold.', styles['Normal'])) body.append(Spacer(1, 10)) body.append( Paragraph( '<strong>If you need more time.</strong> to pay the modified penalty, you can apply for an extension of time by writing to the Approved Officer at the above postal address.', styles['Normal'])) data_tbl2.append(['', body, '']) # Notice to alleged offender (3) body = [] body.append( Paragraph( '<strong>If you want this matter to be dealt with by prosecution in court</strong>, sign here <u>' + gap(80) + '</u> and post this notice to the Approved Officer at the above postal address within 28 days after the date of this notice.', styles['Normal'])) data_tbl2.append(['', body, '']) # Create 2nd table invoice_table_style2 = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 1, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), # Notice to alleged offender ('SPAN', (0, 0), (0, 2)), ('SPAN', (1, 0), (2, 0)), ('SPAN', (1, 1), (2, 1)), ('SPAN', (1, 2), (2, 2)), ]) col_width = [ 40 * mm, 60 * mm, 80 * mm, ] t2 = Table(data_tbl2, style=invoice_table_style2, colWidths=col_width) elements = [] # elements.append(NextPageTemplate('EveryPages2')) elements.append(t1) elements.append(PageBreak()) elements.append(t2) doc.build(elements) return invoice_buffer
def genPrintLabelPDFs(self, labelDataInput, defaultFileName=None, returnBytes=False): """labelDataInput = list of dictionaries formatted as: {DWC Column:'field value'} defaultFileName = the filename to use as the default when saving the pdf file.""" # strip out the site number rows try: labelDataInput = [ x for x in labelDataInput if x.get('specimenNumber') != "#" ] except AttributeError: labelDataInput = [ x for x in labelDataInput if "#" not in x.get('otherCatalogNumbers').split('-')[-1] ] if len(labelDataInput) < 1: # exit early if nothing is left return None # decent default values 140, 90 self.xPaperSize = int(self.settings.get('value_X', 140)) * mm self.yPaperSize = int(self.settings.get('value_Y', 90)) * mm self.relFont = int(self.settings.get('value_RelFont', 12)) # TODO explore adding font options which are already bundled with reportlab self.allowSplitting = 0 self.xMarginProportion = 0 self.yMarginProportion = 0 #Padding on tables are functionally the margins in our use. (We're claiming most of paper) self.xMargin = self.xMarginProportion * self.xPaperSize #Margin set up (dynamically depending on paper sizes. self.yMargin = self.xMarginProportion * self.yPaperSize self.customPageSize = (self.xPaperSize, self.yPaperSize) # check some of the optional label settings, & make adjustments. additionalData = {} if self.settings.get('value_inc_VerifiedBy'): additionalData['verifiedBy'] = self.settings.get( 'value_VerifiedBy') else: additionalData['verifiedBy'] = '' if self.settings.get('value_inc_CollectionName'): additionalData['collectionName'] = self.settings.get( 'value_CollectionName') else: additionalData['collectionName'] = '' # setting these now, to avoid redundant .get calls. incAssociated = self.settings.get('value_inc_Associated') maxAssociated = int(self.settings.get('value_max_Associated')) if not incAssociated: additionalData['associatedTaxa'] = '' for rowData in labelDataInput: if incAssociated: associatedTaxa = rowData['associatedTaxa'] associatedTaxaItems = associatedTaxa.split(', ') if len( associatedTaxaItems ) > maxAssociated: #if it is too large, trunicate it, and append "..." to indicate trunication. associatedTaxa = ', '.join( associatedTaxaItems[:maxAssociated]) + ' ...' rowData['associatedTaxa'] = associatedTaxa for key, value in additionalData.items(): rowData[key] = value tableSty = [ #Default table style ('LEFTPADDING', (0, 0), (-1, -1), 0), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (-1, -1), 0), ('BOTTOMPADDING', (0, 0), (-1, -1), 0) ] #helper functions to keep the 'flowables' code more legible. def Para(textField1, styleKey, prefix='', suffix=''): if len( dfl(textField1) ) > 0: #If the field has a value insert it, otherwise blank row return Paragraph( ('<b>{}</b>'.format(prefix)) + dfl(textField1) + suffix, style=self.stylesheet(styleKey)) else: return Paragraph('', style=self.stylesheet(styleKey)) def verifiedByPara(textField1, styleKey): if len( dfl(textField1) ) > 0: #If the field has a value insert it, otherwise blank row return Paragraph('<i>Verified by {}</i>'.format( dfl(textField1)), style=self.stylesheet(styleKey)) else: return Paragraph('', style=self.stylesheet(styleKey)) def sciName(textfield1, textfield2, styleKey, prefix=''): if len(dfl(textfield1)) > 0: return Paragraph(('<i>{}</i>'.format(dfl(textfield1))) + ' ' + dfl(textfield2), style=self.stylesheet(styleKey)) else: return Paragraph('', style=self.stylesheet(styleKey)) def collectedByPara(textfield1, textfield2, styleKey, prefix=''): if len(dfl(textfield1)) > 0: if len(dfl(textfield2)) > 0: return Paragraph( ('<b>{}</b>'.format(prefix)) + dfl(textfield1) + ' with ' + dfl(textfield2), style=self.stylesheet(styleKey)) else: return Paragraph( ('<b>{}</b>'.format(prefix)) + dfl(textfield1), style=self.stylesheet(styleKey)) else: return Paragraph('', style=self.stylesheet(styleKey)) def cultivationStatusChecker(textfield1, styleKey): if str(dfl(textfield1)) == 'cultivated': return Paragraph('<b>Cultivated specimen</b>', style=self.stylesheet(styleKey)) else: return Paragraph('', style=self.stylesheet('default')) def gpsCoordStringer(textfield1, textfield2, textfield3, textfield4, styleKey): gpsString = [] if len(dfl(textfield1)) > 0: if (dfl(textfield1) and dfl(textfield2)): # min([len(dfl(textfield1)),len(dfl(textfield2))]) testing length control. gpsString.append('<b>GPS: </b>' + dfl(textfield1) + ', ' + dfl(textfield2)) if dfl(textfield3): gpsString.append( ' ± ' + str(round(float(dfl(textfield3)), 0)).split('.')[0] + 'm') if dfl(textfield4): gpsString.append(', <b>Elevation: </b>' + dfl(textfield4) + 'm') return Paragraph(''.join(gpsString), style=self.stylesheet(styleKey)) #############Logo Work################################# ############################################################################## # #logoPath = 'ucht.jpg' # This should be determined by the user dialog open option. # #def getLogo(logoPath): # if logoPath: # return Image(logoPath, width = 40, height =30.6) #These values should be handled dynamically! ######Barcode work(Catalog Number)###### def newHumanText(self): return self.stop and self.encoded[1:-1] or self.encoded def createBarCodes( ): #Unsure of the benefits downsides of using extended vs standard? if len(dfl('catalogNumber')) > 0: barcodeValue = dfl('catalogNumber') else: barcodeValue = self.settings.dummyCatNumber if barcodeValue: code39._Code39Base._humanText = newHumanText #Note, overriding the human text from this library to omit the stopcode ('+') barcode39Std = code39.Standard39( barcodeValue, barHeight=(self.yPaperSize * .10), barWidth=((self.xPaperSize * 0.28) / (len(barcodeValue) * 13 + 35)), humanReadable=True, quiet=False, checksum=0) #^^^Note width is dynamic, but I don't know the significe of *13+35 beyond making it work. return barcode39Std else: return '' elements = [] # a list to dump the flowables into for pdf generation for labelFieldsDict in labelDataInput: def dfl(key): # dict lookup helper function value = labelFieldsDict.get( key, '') # return empty string if no result from lookup. return str(value) #Building list of flowable elements below if (len(dfl('catalogNumber')) > 0) | (self.settings.dummyCatNumber != False): row0 = Table([[ Para('collectionName', 'collectionNameSTY'), createBarCodes() ]], colWidths=(self.xPaperSize * .67, self.xPaperSize * .29), rowHeights=None, style=[ ('VALIGN', (0, 0), (0, -1), 'TOP'), ('ALIGN', (0, 0), (0, 0), 'LEFT'), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ]) else: row0 = Para('collectionName', 'collectionNameSTY') row1 = Table([[Para('labelProject', 'labelProjectSTY')], [verifiedByPara('verifiedBy', 'verifiedBySTY')]], colWidths=self.xPaperSize * .98, rowHeights=None, style=[('BOTTOMPADDING', (0, 0), (-1, -1), 2)]) #bookmark #ScientificName Row Dynamic Formatting scientificNameElement = sciName('scientificName', 'scientificNameAuthorship', 'sciNameSTY') try: #Test if Scienftific Name can Share a row with Event Date. scientificNameElement.wrap( 1400, 1400 ) #Test wrap the string in a large environment to get it's desired ideal width. sciNameParaWidth = scientificNameElement.getActualLineWidths0( )[0] sciHeight = scientificNameElement.height except (AttributeError, IndexError) as e: sciNameParaWidth = 0 sciHeight = 0 if sciNameParaWidth > self.xPaperSize * .96: #If the string is so large as to not fit, even alone then shrink font and split lines into two rows. row2 = Table( [ [Para('eventDate', 'dateSTY')], [ Spacer(width=self.xPaperSize * .98, height=sciHeight) ], #Add spacer between rows for formatting. [ sciName('scientificName', 'scientificNameAuthorship', 'sciNameSTYSmall') ] ], colWidths=self.xPaperSize * .98, rowHeights=None, style=tableSty) elif sciNameParaWidth > self.xPaperSize * -1: #If the string is too big to share row with event date, split lines into rows. row2 = Table( [ [Para('eventDate', 'dateSTY')], [ Spacer(width=self.xPaperSize * .98, height=sciHeight) ], #Add spacer between rows for formatting. [ sciName('scientificName', 'scientificNameAuthorship', 'sciNameSTY') ] ], colWidths=self.xPaperSize * .98, rowHeights=None, style=tableSty) else: row2 = Table([[ sciName('scientificName', 'scientificNameAuthorship', 'sciNameSTY'), Para('eventDate', 'dateSTY') ]], colWidths=(self.xPaperSize * .80, self.xPaperSize * .18), rowHeights=None, style=tableSty) row3 = Table([[Para('locality', 'default')]], rowHeights=None, style=tableSty) #Associated Taxa Dynamic Formatting if dfl( 'associatedTaxa' ) == '': #If associated taxa is not used, give up the y space. associatedTaxaHeight = 0 associatedTaxaStyle = 'defaultSTYSmall' #This entire block is not functioning the way it was planned to. else: associatedTaxaHeight = .15 * self.yPaperSize #Otherwise, devote some space, then test it's useage. associatedTaxaElement = Para( 'associatedTaxa', 'default', 'Associated taxa: ') #Test build for height try: associatedTaxaParaHeight = associatedTaxaElement.wrap( self.xPaperSize * .98, 1 )[1] #Test wrap the string in a large environment to get necessary height. except (AttributeError, IndexError) as e: print('error ', e) associatedTaxaParaHeight = 0 if associatedTaxaParaHeight > associatedTaxaHeight: #If the string is too large, reduce the font size. associatedTaxaStyle = 'defaultSTYSmall' else: associatedTaxaStyle = 'default' #otherwise, use the normal height row4 = Table([[ Para('associatedTaxa', associatedTaxaStyle, 'Associated taxa: ') ]], rowHeights=None, style=tableSty) #Note, associatedTaxa only reduces size if it is too large. At some extream point we'll need to consider trunication. if dfl('individualCount') != '': row5 = Table([[ Para('habitat', 'default', 'Habitat: '), Para('individualCount', 'rightSTY', 'Approx. ≥ ', ' on site.') ]], colWidths=(self.xPaperSize * .68, self.xPaperSize * .30), rowHeights=None, style=[('VALIGN', (1, 0), (1, 0), 'CENTER'), ('ALIGN', (0, 0), (0, 0), 'LEFT'), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ('LEFTPADDING', (0, 0), (-1, -1), 0), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (-1, -1), 0), ('BOTTOMPADDING', (0, 0), (-1, -1), 0)]) else: row5 = Table([[Para('habitat', 'default', 'Habitat: ')]], style=tableSty) if dfl( 'establishmentMeans' ) == 'cultivated': #If establishmentMeans status is not 'cultivated' (based on cultivated status in mobile app) then forfit the space in case Substrate field is long. row6 = Table([[ Para('substrate', 'default', 'Substrate: '), cultivationStatusChecker('establishmentMeans', 'rightSTY') ]], colWidths=(self.xPaperSize * .68, self.xPaperSize * .30), rowHeights=None, style=tableSty) else: row6 = Table([[Para('substrate', 'default', 'Substrate: ')]], style=tableSty) row7 = [ collectedByPara('recordedBy', 'associatedCollectors', 'default', 'Collected by: ') ] row6_5 = Table( [[Para('locationRemarks', 'default', 'Location Remarks: ')]], style=tableSty) #Note locationRemarks is in testing, may not stay! row6_7 = Table( [[Para('occurrenceRemarks', 'default', 'Occurence Remarks: ')] ], style=tableSty) if dfl('identifiedBy') != '': row7_5 = Table( [[Para('identifiedBy', 'default', 'Determined by: ')]], style=tableSty) # TODO: Add all tableList (row) objects to a loop which checks for content and appends else returns None # ... Then Clean tableList for None objects tableList = [[row0], [row1], [row2], [row3], [row4], [row5], [row6], [row6_5], [row6_7], [row7]] #Testing if GPS String can fit on one row with the field number. If not, split them into two rows. gpsStrElement = gpsCoordStringer('decimalLatitude', 'decimalLongitude', 'coordinateUncertaintyInMeters', 'minimumElevationInMeters', 'rightSTYSmall') try: gpsStrElement.wrap(self.xPaperSize * .98, self.yPaperSize * .98) try: gpsParaWidth = gpsStrElement.getActualLineWidths0()[0] except IndexError: gpsParaWidth = 0 except AttributeError: gpsParaWidth = 0 if gpsParaWidth > self.xPaperSize * .65: row8 = Table([[ Para('otherCatalogNumbers', 'default', 'Field Number: ') ]], style=tableSty) row9 = Table([[gpsStrElement]], style=tableSty) tableList.append([row8]) if dfl('identifiedBy') != '': tableList.append([row7_5]) tableList.append([row9]) else: row8 = Table([[ Para('otherCatalogNumbers', 'default', 'Field Number: '), gpsStrElement ]], colWidths=(self.xPaperSize * .33, self.xPaperSize * .65), rowHeights=None, style=tableSty) tableList.append([row8]) if dfl('identifiedBy') != '': tableList.append([row7_5]) # append the determined by field docTableStyle = [ #Cell alignment and padding settings (not text align within cells) ('VALIGN', (0, 3), (0, -1), 'BOTTOM'), #Rows 4-end align to bottom ('ALIGN', (0, 0), (-1, -1), 'CENTER'), #All rows align to center ('LEFTPADDING', (0, 0), (-1, -1), 0), #ALL Rows padding on left to none ('RIGHTPADDING', (0, 0), (-1, -1), 0), #ALL Rows padding on right to none ('TOPPADDING', (0, 0), (-1, -1), 3), #ALL Rows padding on top to none ('BOTTOMPADDING', (0, 0), (-1, -1), 0), #ALL Rows padding on Bottom to none ('BOTTOMPADDING', (0, 0), (0, 0), 3), #ALL Rows padding on Bottom to none ('TOPPADDING', (0, 1), (0, 1), 6), #Row 2 top padding to 6 ('TOPPADDING', (0, 2), (0, 2), 6), #Row 3 top padding to 6 ('BOTTOMPADDING', (0, 2), (0, 2), 6), #Row 3 bottom padding to 6 #('NOSPLIT', (0,0),(-1,-1)), #Makes Error if it won't fit. We should raise this error to user! ] docTable = Table( tableList, style=docTableStyle) #build the table to test it's height wid, hei = docTable.wrap( 0, 0) #Determines how much space is used by the table spaceRemaining = (self.yPaperSize - hei - 10 ) #Determine how much is left on the page spaceFiller = [ Spacer(width=0, height=(spaceRemaining / 3)) ] #assign half the remaining space to a filler (to distrib into two places. tableList.insert( 4, spaceFiller ) #build from bottom up because it is less confusing for the index values. tableList.insert(3, spaceFiller) tableList.insert(2, spaceFiller) docTable = Table(tableList, style=docTableStyle) #build the final table #Add the flowables to the elements list. elements.append(docTable) elements.append(PageBreak()) #Build the base document's parameters. if returnBytes: # if we only want to make a preview save it to a stream byteStream = io.BytesIO() labelFileName = byteStream elif defaultFileName: labelFileName = defaultFileName #labelFileName, _ = QFileDialog.getSaveFileName(None, 'Save Label PDF', defaultFileName, 'PDF(*.pdf)') else: labelFileName, _ = QFileDialog.getSaveFileName( None, 'Save Label PDF', os.getenv('HOME'), 'PDF(*.pdf)') if not labelFileName: # If the user canceled the dialog return # TODO fill in title and author based on select form_view or settings info doc = BaseDocTemplate(labelFileName, pagesize=self.customPageSize, pageTemplates=[], showBoundary=0, leftMargin=self.xMargin, rightMargin=self.xMargin, topMargin=self.yMargin, bottomMargin=self.yMargin, allowSplitting=self.allowSplitting, title=None, author=None, _pageBreakQuick=1, encrypt=None) #Function to build the pdf def build_pdf(flowables): """ actually loads the flowables into the document """ doc.addPageTemplates([ PageTemplate(onPage=self.labelSetup, frames=[ platypusFrame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, topPadding=0, bottomPadding=0, id=None), ]), ]) try: doc.build(flowables) except LayoutError: raise LayoutError try: build_pdf(elements) except LayoutError: # if there is a layout error, raise it raise LayoutError if returnBytes: # If a preview is being generated just return the bytes # calling the byte stream "labelFileName" is a fast and dirty # workaround to keep existing code functional pdfBytes = labelFileName.getvalue( ) # save the stream to a variable labelFileName.close() # close the buffer down return pdfBytes # return the results #Open the file after it is built (maybe change/remove this later? Idealy, a preview or something def open_file(filename): if sys.platform == "win32": os.startfile(filename) else: opener = "open" if sys.platform == "darwin" else "xdg-open" subprocess.call([opener, filename]) open_file(labelFileName)
def _create_pdf(invoice_buffer, legal_case, brief_of_evidence_record_of_interviews): every_page_frame = Frame( PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 2 * PAGE_MARGIN, id='EveryPagesFrame', ) #showBoundary=Color(0, 1, 0)) every_page_template = PageTemplate( id='EveryPages', frames=[ every_page_frame, ], ) doc = BaseDocTemplate( invoice_buffer, pageTemplates=[ every_page_template, ], pagesize=A4, ) # showBoundary=Color(1, 0, 0)) # Common col_width_head = [ 85 * mm, 25 * mm, 85 * mm, ] col_width_details = [27 * mm, 27 * mm, 71 * mm, 30 * mm, 36 * mm] col_width_for_court = [ 27 * mm, 24 * mm, 18 * mm, 58 * mm, 47 * mm, 17 * mm ] FONT_SIZE_L = 11 FONT_SIZE_M = 10 FONT_SIZE_S = 8 styles = StyleSheet1() styles.add( ParagraphStyle( name='Normal', fontName='Helvetica', fontSize=FONT_SIZE_M, spaceBefore=7, # space before paragraph spaceAfter=7, # space after paragraph leading=12)) # space between lines styles.add( ParagraphStyle(name='BodyText', parent=styles['Normal'], spaceBefore=6)) styles.add( ParagraphStyle(name='Italic', parent=styles['BodyText'], fontName='Helvetica-Italic')) styles.add( ParagraphStyle(name='Bold', parent=styles['BodyText'], fontName='Helvetica-Bold', alignment=TA_CENTER)) styles.add( ParagraphStyle(name='Right', parent=styles['BodyText'], alignment=TA_RIGHT)) styles.add( ParagraphStyle(name='Centre', parent=styles['BodyText'], alignment=TA_CENTER)) elements = [] for boe in brief_of_evidence_record_of_interviews: offender = boe.offender.person offence = boe.offence if not offender or not offence: continue # Generate texts accused_text = offender.get_full_name() accused_dob_text = offender.dob.strftime( '%d/%m/%Y') if offender.dob else '' accused_address_text = offender.residential_address offence_period = offence.occurrence_datetime_from.strftime("%d/%m/%Y") if offence.occurrence_from_to: offence_period += ' to ' + offence.occurrence_datetime_to.strftime( "%d/%m/%Y") offence_place = str(offence.location) offence_description = offence.details # Head (col, row) invoice_table_style = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 0, colors.white), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ]) style_tbl_left = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ]) style_tbl_right = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ]) data_left = Table([[ Paragraph( 'MAGISTRATES COURT of WESTERN<br />' 'AUSTRALIA<br />' '<strong><font size="' + str(FONT_SIZE_L) + '">PROSECUTION NOTICE</font></strong><br />' '<i>Criminal Procedure Act 2004</i><br />' 'Criminal Procedure Regulations 2005 - Form 3', styles['Centre']), ]], style=style_tbl_left) data_right = Table([ [Paragraph('Court number', styles['Normal']), ''], [Paragraph('Magistrates court at', styles['Normal']), ''], [Paragraph('Date lodged', styles['Normal']), ''], ], style=style_tbl_right, rowHeights=[ 7.8 * mm, 7.8 * mm, 7.8 * mm, ]) tbl_head = Table( [[data_left, '', data_right]], style=invoice_table_style, colWidths=col_width_head, ) # Details of alleged offence rowHeights = [6 * mm, 6 * mm, 6 * mm, 30 * mm, 6 * mm] style_tbl_details = TableStyle([ ('VALIGN', (0, 0), (0, 0), 'TOP'), ('VALIGN', (1, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('SPAN', (0, 0), (0, 4)), ('SPAN', (2, 0), (4, 0)), ('SPAN', (2, 1), (4, 1)), ('SPAN', (2, 2), (4, 2)), ('SPAN', (2, 3), (4, 3)), ('SPAN', (2, 4), (4, 4)), ]) data = [] data.append([ Paragraph( '<strong>Details of alleged offence</strong><br />' '<i><font size="' + str(FONT_SIZE_S) + '">[This description must comply with the CPA Schedule 1 clause 5.]</font></i>', styles['Normal']), Paragraph('Accused', styles['Normal']), Paragraph(get_font_str(accused_text), styles['Normal']), '', '', ]) data.append([ '', Paragraph('Date or period', styles['Normal']), Paragraph(get_font_str(offence_period), styles['Normal']), '', '' ]) data.append([ '', Paragraph('Place', styles['Normal']), Paragraph(get_font_str(offence_place), styles['Normal']), '', '' ]) data.append([ '', Paragraph('Description', styles['Normal']), Paragraph(get_font_str(offence_description), styles['Normal']), '', '' ]) data.append( ['', Paragraph('Written law', styles['Normal']), '', '', '']) tbl_details = Table(data, style=style_tbl_details, colWidths=col_width_details, rowHeights=rowHeights) # Notice to accused style_tbl_notice = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('SPAN', (1, 0), (4, 0)), ]) data = [] data.append([ Paragraph('<strong>Notice to accused</strong>', styles['Normal']), Paragraph( 'You are charged with the offence described above, or the offences described in any attachment to this notice. The charge(s) will be dealt with by the above court.', styles['Normal']), '', '', '', ]) tbl_notice = Table(data, style=style_tbl_notice, colWidths=col_width_details) # Accused's Details rowHeights = [4.5 * mm, 6 * mm, 6 * mm] style_tbl_accused = TableStyle([ ('VALIGN', (0, 0), (0, -1), 'TOP'), ('VALIGN', (1, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('SPAN', (0, 0), (0, 2)), ('SPAN', (1, 0), (4, 0)), ('SPAN', (3, 1), (4, 1)), ('SPAN', (2, 2), (4, 2)), ]) data = [] data.append([ Paragraph('<strong>Accused\'s Details</strong>', styles['Normal']), Paragraph( '<i><font size="' + str(FONT_SIZE_S) + '">[This description must comply with the CPA Schedule 1 clause 4.]</font></i>', styles['Normal']), '', '', '', ]) data.append([ '', Paragraph('Date of Birth', styles['Normal']), Paragraph(get_font_str(accused_dob_text), styles['Normal']), Paragraph('Male / Female', styles['Normal']), '', ]) data.append([ '', Paragraph('Address', styles['Normal']), Paragraph(get_font_str(accused_address_text), styles['Normal']), '', '', ]) tbl_accused = Table(data, style=style_tbl_accused, colWidths=col_width_details, rowHeights=rowHeights) # Prosecutor rowHeights = [ 4.5 * mm, 6 * mm, 6 * mm, 6 * mm, 15 * mm, 4.5 * mm, 15 * mm, 6 * mm ] style_tbl_prosecutor = TableStyle([ ('VALIGN', (0, 0), (0, -1), 'TOP'), ('VALIGN', (1, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('VALIGN', (2, 6), (-1, 6), 'BOTTOM'), ('SPAN', (0, 0), (0, 1)), # col: Prosecutor ('SPAN', (0, 2), (0, 6)), # col: Person issuing this notice ('SPAN', (1, 5), (1, 6)), # col: Witness's signature ('SPAN', (1, 0), (4, 0)), ('SPAN', (1, 1), (4, 1)), ('SPAN', (2, 4), (4, 4)), ('SPAN', (2, 5), (4, 5)), ('SPAN', (2, 6), (4, 6)), ('SPAN', (1, 7), (4, 7)), ]) data = [] data.append([ Paragraph('<strong>Prosecutor</strong>', styles['Normal']), Paragraph( '<i><font size="' + str(FONT_SIZE_S) + '">[Identify the prosecutor in accordance with the CPA Schedule 1 clause 3.]</font></i>', styles['Normal']), '', '', '', ]) data.append([ '', '', '', '', '', ]) data.append([ Paragraph('<strong>Person issuing this notice</strong>', styles['Normal']), Paragraph('Full name', styles['Normal']), '', Paragraph('official title', styles['Normal']), '', ]) data.append([ '', Paragraph('Work address', styles['Normal']), '', Paragraph('Work telephone', styles['Normal']), '', ]) data.append([ '', Paragraph('Signature', styles['Normal']), '', '', '', ]) data.append([ '', Paragraph('Witness\'s Signature', styles['Normal']), Paragraph( '<i><font size="' + str(FONT_SIZE_S) + '">[A witness may not be needed. See the CPA section 23.]</font></i>', styles['Normal']), '', '', ]) data.append([ '', '', Paragraph( '<font size="' + str(FONT_SIZE_S) + '">Justice of the Peace or Prescribed Court Officer</font>', styles['Normal']), '', '', ]) data.append([ Paragraph('<strong>Date</strong>', styles['Normal']), Paragraph('This prosecution notice is signed on', styles['Normal']), '', '', '', ]) tbl_prosecutor = Table(data, style=style_tbl_prosecutor, colWidths=col_width_details, rowHeights=rowHeights) # For Court Use Only rowHeights_court = [ 6 * mm, 10 * mm, 6 * mm, 6 * mm, 6 * mm, 6 * mm, 6 * mm, 6 * mm, 6 * mm, 6 * mm, 23 * mm, 17 * mm ] style_tbl_for_court = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('VALIGN', (3, 11), (5, 11), 'BOTTOM'), ('VALIGN', (0, 10), (2, 11), 'TOP'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('SPAN', (0, 0), (5, 0)), ('SPAN', (3, 1), (4, 1)), ('SPAN', (3, 2), (4, 2)), ('SPAN', (3, 3), (4, 3)), ('SPAN', (3, 4), (4, 4)), ('SPAN', (3, 5), (4, 5)), ('SPAN', (3, 6), (4, 6)), ('SPAN', (1, 7), (2, 7)), # Guilty / not guilty ('SPAN', (1, 8), (2, 8)), ('SPAN', (1, 9), (2, 9)), # Convicted / acquitted ('SPAN', (3, 7), (5, 10)), # Penalty and other orders ('SPAN', (4, 11), (5, 11)), ('SPAN', (0, 10), (2, 11)), # <== This has a bug...? ]) data = [] data.append([ Paragraph('<i>For Court User Only</i>', styles['Bold']), '', '', '', '', '' ]) data.append([ Paragraph('Date', styles['Centre']), Paragraph('Appearance by accused', styles['Centre']), Paragraph('Counsel', styles['Centre']), Paragraph('Record of court proceedings', styles['Centre']), '', Paragraph('Judicial officer', styles['Centre']), ]) data.append(['', Paragraph('Y / N', styles['Bold']), '', '', '', '']) data.append(['', Paragraph('Y / N', styles['Bold']), '', '', '', '']) data.append(['', Paragraph('Y / N', styles['Bold']), '', '', '', '']) data.append(['', Paragraph('Y / N', styles['Bold']), '', '', '', '']) data.append(['', Paragraph('Y / N', styles['Bold']), '', '', '', '']) data.append([ Paragraph('Plea', styles['Bold']), Paragraph('Guilty / not guilty', styles['Bold']), '', [ Paragraph('Penalty and other orders', styles['Centre']), Paragraph('<strong>Fine</strong>', styles['Normal']), Paragraph('<strong>Costs</strong>', styles['Normal']), Paragraph('<strong>Other</strong>', styles['Normal']) ], '', '', ]) data.append([ Paragraph('Date of plea', styles['Bold']), '', '', '', '', '', ]) data.append([ Paragraph('<strong>Judgement</strong>', styles['Centre']), Paragraph('<strong>Conficted / acquitted</strong>', styles['Centre']), '', '', '', '', ]) data.append([ Paragraph('<strong>Victim impact statement available</strong>', styles['Centre']), '', '', '', '', '' ]) data.append([ '', '', '', Paragraph('<strong>Judicial officer</strong>', styles['Centre']), Paragraph('<strong>Date:</strong>', styles['Normal']), '', ]) tbl_for_court = Table(data, style=style_tbl_for_court, colWidths=col_width_for_court, rowHeights=rowHeights_court) ############# # PageBreak # ############# # Court Number rowHeights = [ 10 * mm, ] col_width_court_number = [ 30 * mm, 70 * mm, ] style_tbl_for_court_number = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ]) data = [] data.append([Paragraph('Court number', styles['Normal']), '']) tbl_for_court_number = OffsetTable(data, x_offset=45.5 * mm, style=style_tbl_for_court_number, colWidths=col_width_court_number, rowHeights=rowHeights) # Table above style_array = [ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ] for row_num in range(0, 29): style_array.append(('SPAN', (3, row_num), (4, row_num))) style_tbl_above = TableStyle(style_array) data = [] data.append([ Paragraph('Date', styles['Centre']), Paragraph('Appearance by accused', styles['Centre']), Paragraph('Counsel', styles['Centre']), Paragraph('Record of court proceedings', styles['Centre']), '', Paragraph('Judicial officer', styles['Centre']), ]) for row_num in range(0, 28): data.append([ '', Paragraph('<strong>Y / N</strong>', styles['Centre']), '', '', '', '' ]) tbl_above = Table(data, style=style_tbl_above, colWidths=col_width_for_court) # Table below style_array = [ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ] for row_num in range(0, 8): style_array.append(('SPAN', (2, row_num), (5, row_num))) style_tbl_below = TableStyle(style_array) data = [] data.append([ Paragraph('Date', styles['Centre']), Paragraph('Clerk\'s Initial', styles['Centre']), Paragraph('Registry record', styles['Centre']), '', '', '', ]) for row_num in range(0, 7): data.append(['', '', '', '', '', '']) tbl_below = Table(data, style=style_tbl_below, colWidths=col_width_for_court, rowHeights=8.5 * mm) # Append tables to the elements to build gap_between_tables = 1.5 * mm elements.append(tbl_head) elements.append(tbl_details) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_notice) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_accused) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_prosecutor) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_for_court) elements.append(PageBreak()) elements.append(tbl_for_court_number) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_above) elements.append(Spacer(0, gap_between_tables)) elements.append(tbl_below) doc.build(elements) return invoice_buffer