def get_metadata_page(self, recipient): MetadataPage = [] MetadataPage.append( Paragraph(self.report_title, self.report_title_style)) MetadataPage.append(Paragraph("Overview", self.section_title_style)) overview_body = "Submitted by: {0}<br/>".format( self.get_user_identifier(self.user)) if recipient: overview_body = overview_body + "Submitted on: {0}<br/>".format( localtime( self.report.submitted_to_school).strftime(date_format)) overview_body = overview_body + \ """Record Created: {0} Last Edited: {1}""".format(localtime(self.report.added).strftime(date_format), localtime(self.report.last_edited).strftime(date_format) if self.report.last_edited else "<i>Not edited</i>") overview_body = overview_body.replace('\n', '<br />\n') MetadataPage.append(Paragraph(overview_body, self.body_style)) if recipient: MetadataPage.append( Paragraph("Contact Preferences", self.section_title_style)) contact_body = """Name: {0} Phone: {1} Voicemail preferences: {2} Email: {3} Notes on preferred contact time of day, gender of admin, etc.:""".format( self.report.contact_name or "<i>None provided</i>", self.report.contact_phone, self.report.contact_voicemail or "None provided", self.report.contact_email).replace('\n', '<br />\n') MetadataPage.append(Paragraph(contact_body, self.body_style)) MetadataPage.append( Paragraph(self.report.contact_notes or "None provided", self.notes_style)) MetadataPage.append(Paragraph("Key", self.section_title_style)) key = ListFlowable([ ListItem(Paragraph("Unselected option", self.answers_style), value=self.unselected, leftIndent=45), ListItem(Paragraph("<b>Selected option</b>", self.answers_style), value=self.selected, leftIndent=45), ListItem(Paragraph("Free text response", self.answers_style), value=self.free_text, leftIndent=45) ], bulletType='bullet', style=self.answers_list_style) MetadataPage.append(key) MetadataPage.append(PageBreak()) return MetadataPage
def list_flowable_squares(): doc = SimpleDocTemplate("list_flowable_squares.pdf", pagesize=letter) styles = getSampleStyleSheet() normal = styles['Normal'] story = [] flowables = [ Paragraph('Paragraph numero uno', normal), ListItem(Paragraph('Paragraph #2', normal), bulletColor="blue"), Paragraph('Paragraph #3', normal), ] flowables.append( ListFlowable([ Paragraph("I'm a sublist item", normal), ListItem(Paragraph("I'm another sublist item", normal), bulletColor='blue'), ListItem(Paragraph("I'm the last sublist item", normal), bulletColor='red') ], bulletType='bullet', start='square')) lflow = ListFlowable(flowables, bulletType='I') story.append(lflow) doc.build(story)
def soil_section(rain_tot2, runoff_tot2, evap_tot2, rech_soil_tot2, deficit_tot, soil_tdelta, soil_plot_path): soil_section = [] #Set the style styles = getSampleStyleSheet() styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY, leading=24)) #Add title title = 'Soil water budget' ptext = '<font size=24>%s</font>' % title soil_section.append(Paragraph(ptext, styles["Justify"])) #Add vertical space soil_section.append(Spacer(1, 30)) #Add text ptext = '<font size=12>The soil water budget includes the following components:</font>' soil_section.append(Paragraph(ptext, styles["Justify"])) #Bullet list budget_components = ListFlowable([ ListItem(Paragraph("rainfall (inflow term)", styles['Normal']), value='circle'), ListItem(Paragraph("runoff (outflow term)", styles['Normal']), value='circle'), ListItem(Paragraph("evapotranspiration (outflow term)", styles['Normal']), value='circle'), ListItem(Paragraph("percolation to the water table (outflow term)", styles['Normal']), value='circle') ], bulletType='bullet', start='circle') soil_section.append(budget_components) #Add vertical space soil_section.append(Spacer(1, 30)) #Add text ptext = '<font size=12>According to model results, over the simulation period (%s days long), the total rainfall was %s mm.\ We can also estimate: %s mm of runoff, %s mm of evapotranspiration and %s mm of percolation to the water table.\ This results in a water deficit of %s mm.</font>' % ( soil_tdelta, rain_tot2, runoff_tot2, evap_tot2, rech_soil_tot2, deficit_tot) soil_section.append(Paragraph(ptext, styles["Justify"])) #Add plot img = Image(soil_plot_path, 7 * inch, 5 * inch) soil_section.append(img) #Add vertical space soil_section.append(Spacer(1, 30)) return soil_section
def test1(self): styleSheet = getSampleStyleSheet() doc = SimpleDocTemplate(outputfile('test_platypus_lists1.pdf')) story = [] sty = [ ('GRID', (0, 0), (-1, -1), 1, colors.green), ('BOX', (0, 0), (-1, -1), 2, colors.red), ] normal = styleSheet['BodyText'] lpSty = normal.clone('lpSty', spaceAfter=18) data = [[ str(i + 1), Paragraph("xx " * (i % 10), styleSheet["BodyText"]), Paragraph(("blah " * (i % 40)), normal) ] for i in xrange(5)] data1 = [[ str(i + 1), Paragraph(["zz ", "yy "][i] * (i + 3), styleSheet["BodyText"]), Paragraph(("duh " * (i + 3)), normal) ] for i in xrange(2)] OL = ListFlowable([ Paragraph("A table with 5 rows", lpSty), Table(data, style=sty, colWidths=[50, 100, 200]), ListItem( Paragraph("A sublist", normal), value=7, ), ListFlowable( [ Paragraph("Another table with 3 rows", normal), Table(data[:3], style=sty, colWidths=[60, 90, 180]), Paragraph(TEXTS[0], normal), ], bulletType='i', ), Paragraph("An unordered sublist", normal), ListFlowable( [ Paragraph("A table with 2 rows", normal), ListItem(Table(data1, style=sty, colWidths=[60, 90, 180]), bulletColor='green'), ListItem(Paragraph(TEXTS[2], normal), bulletColor='red', value='square') ], bulletType='bullet', start='circle', ), Paragraph(TEXTS[1], normal), ]) story.append(OL) doc.build(story)
def add_sub_item(self, item): """Add a sub item container to _in_progress_item. """ item_list = self._build_item(item) value = 1 if len(self._in_progress_item) == 1 else None self._in_progress_item.append( ListItem(item_list, bulletType=self._sub_item_bullet_type, value=value))
def listify(input): listItems = [] for item in input: listItem = ListItem(Paragraph((item), styleN), leftIndent=35, value='-') listItems.append(listItem) output = ListFlowable(listItems, bulletType='bullet') return output
def add_terms(self, list): style = ParagraphStyle( name='Normal', fontName='Arabic', fontSize=8, ) table = ListFlowable([ ListItem(Paragraph(x, style), leftIndent=35, bulletColor='black') for x in list ], bulletType='bullet') return table
def handle_block(block): paragraphs = [] for tag in block: if isinstance(tag, NavigableString): text = tag.strip() if text: paragraphs.append(Paragraph(text, styles['Normal'])) elif tag.name in {'ul', 'ol'}: style = styles['Normal'] if tag.name == 'ul': bullet = 'bullet' elif tag.name == 'ol': bullet = '1' paragraphs.append( ListFlowable( [ ListItem(Paragraph(bullet_item.get_text(), style)) for bullet_item in tag.find_all('li') ], bulletType=bullet, )) elif tag.name in {'table'}: paragraphs.append( Table( [[ Paragraph(cell.get_text(), styles['Normal']) for cell in row.find_all({'td', 'th'}) ] for row in tag.find_all('tr')], colWidths='*', style=TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('LINEABOVE', (0, 0), (-1, -1), 1, DARK_GREY), ]), )) else: if tag.name in {'p'}: style = styles['Normal'] elif tag.name == 'h2': style = styles['Heading2'] elif tag.name == 'h3': style = styles['Heading3'] elif tag.name == 'h4': style = styles['Heading4'] elif tag.name == 'h5': style = styles['Heading5'] text = tag.get_text() if text: paragraphs.append(Paragraph(text, style)) return paragraphs
def makeBulletList(list): bullets = ListFlowable( [ ListItem( p_bullet(x), leftIndent=10, bulletColor='black', value='circle', bulletOffsetY=-2.88 ) for x in list ], bulletType='bullet', bulletFontSize=3, leftIndent=5 ) return bullets
def bullet_list(self, body, level): items = [] for text_line in body.split('<br/>'): try: bullet_text = ListItem(Paragraph(text_line, self.style['bullet_list']), leftIndent=level * 35, value='bulletchar') items.append(bullet_text) except Exception as e: print('Error Creating PDF: ' + str(e)) return ListFlowable(items, bulletType='bullet', start='bulletchar')
def list_flowable_demo(): doc = SimpleDocTemplate("list_flowable_demo.pdf", pagesize=letter) styles = getSampleStyleSheet() normal = styles['Normal'] story = [] flowables = [ Paragraph('Paragraph numero uno', normal), ListItem(Paragraph('Paragraph #2', normal), bulletColor="blue", value=5), Paragraph('Paragraph #3', normal), ] lflow = ListFlowable(flowables) story.append(lflow) doc.build(story)
def pdf_gen(report, summary=None): """This function formats the summary report using the content from report_content.yaml to populate the paragraphs, titles, and headers. The tables are populated via the Report param which has all the dataframes. @param report: Report object @param summary: list, replay summary """ with open("report_content.yaml", 'r') as stream: docs = yaml.safe_load(stream) style = g_stylesheet.get('styles') elems = [] # elements array used to build pdf structure pdf = SimpleDocTemplate(f"{report.replay_id}_report.pdf", pagesize=letter, leftMargin=0.75 * inch, rightMargin=0.75 * inch, topMargin=0.75 * inch, bottomMargin=0.75 * inch ) # title and subtitle and cluster info table elems.append(Paragraph(docs['title'], style['Title'])) elems.append(Paragraph(sub_yaml_vars(report, docs['subtitle']), style['Heading4'])) cluster_info = pd.DataFrame.from_dict(report.cluster_details, orient='index') elems.append(Table(df_to_np(report.cluster_details.keys(), cluster_info.transpose()), hAlign='LEFT', style=g_stylesheet.get('table_style'))) # replay summary if summary is not None: elems.append(Paragraph(f"Replay Summary", style['Heading4'])) elems.append(ListFlowable([ListItem(Paragraph(x, style['Normal'])) for x in summary], bulletType='bullet')) elems.append(Spacer(0, 5)) elems.append(Paragraph(docs['report_paragraph'], style['Normal'])) # glossary section elems.append(Paragraph(docs['glossary_header'], style['Heading4'])) elems.append(Paragraph(docs['glossary_paragraph'], style['Normal'])) elems.append(ListFlowable([ListItem(Paragraph(x, style['Normal'])) for x in docs['glossary']], bulletType='bullet')) elems.append(Spacer(0, 5)) # access data section elems.append(Paragraph(docs['data_header'], style['Heading4'])) elems.append(Paragraph(sub_yaml_vars(report, docs['data_paragraph']), style['Normal'])) elems.append(ListFlowable([ListItem(Paragraph(x, style['Normal'])) for x in docs['raw_data']], bulletType='bullet')) elems.append(Spacer(0, 5)) elems.append(Paragraph(sub_yaml_vars(report, docs['agg_data_paragraph']), style['Normal'])) # notes section elems.append(Paragraph(docs['notes_header'], style['Heading4'])) elems.append(Paragraph(docs['notes_paragraph'], style['Normal'])) elems.append(ListFlowable([ListItem(Paragraph(x, style['Normal'])) for x in docs['notes']], bulletType='bullet')) elems.append(PageBreak()) # page 2: cluster details # query breakdown build_pdf_tables(elems, docs['query_breakdown'], report) elems.append(Spacer(0, 5)) # histogram and description image_path = hist_gen(x_data=report.feature_graph['sec_start'], y_data=report.feature_graph['count'], title=docs['graph'].get('title'), x_label='Average Elapsed Time (s)') desc = Paragraph(docs['graph'].get('paragraph'), style['Normal']) data = [[Image(image_path, width=300, height=200, hAlign='LEFT'), desc]] elems.append(Table(data, style=TableStyle([('VALIGN', (0, 0), (-1, -1), 'MIDDLE')]))) elems.append(Spacer(0, 5)) # cluster metrics table build_pdf_tables(elems, docs['cluster_metrics'], report) elems.append(PageBreak()) # page 3+ measure tables build_pdf_tables(elems, docs['measure_tables'], report) # build 5 measure tables all at once # build pdf pdf.build(elems, onFirstPage=partial(first_page, report=report), onLaterPages=partial(later_pages, report=report)) os.remove(image_path) return pdf.filename
def pdf_demo_11(file): doc = SimpleDocTemplate(file) style_sheet = getSampleStyleSheet() para_style = style_sheet['BodyText'] # see dir(para_style) to see list of attributes which can be changed para_style.alignment = TA_JUSTIFY para_style.spaceBefore = 18 head_style = style_sheet['Heading2'] story = [] story.append(Paragraph("Paragraphs of text", head_style)) for i in range(10): s = f"This <strong>is</strong> a <em>paragraph</em> {i} with ten sentences using <strong> and <em> tags. " * 10 p = Paragraph(s, para_style) story.append(p) # Spacers currently leave vertical space even though they have parameters for horizontal and vertical story.append(PageBreak()) story.append(Paragraph("Examples of styles", head_style)) for style_name, style in style_sheet.byName.items(): style_description = f"{style_name} - {type(style).__name__}" # Using duck typing to try out the sample styles try: p = Paragraph(style_description, style) except AttributeError: # ListStyle doesn't have fontName attribute so can't be used with a Paragraph p = Paragraph(style_description, para_style) story.append(p) story.append( Paragraph("Builtin functions and classes listed in two columns", head_style)) list_style = getSampleStyleSheet()["OrderedList"] list_style.bulletFontName = "Courier" list_style.bulletFontSize = 10 list_style.leftIndent = 24 list_items_builtins = [ ListItem(Paragraph(b, getSampleStyleSheet()["Normal"])) for b in dir(builtins) ] story.append( BalancedColumns( F=[ListFlowable(list_items_builtins, style=list_style)], nCols=2)) story.append(PageBreak()) # If whitespace important use Preformatted rather than Paragraph story.append(Paragraph("Formatting text using whitespace", head_style)) story.append( Preformatted( r""" ____ _ _ | _ \ (_) ( ) | |_) | ___ __ _ _ _ __ _ __ ___ _ __ ___|/ | _ < / _ \/ _` | | '_ \| '_ \ / _ \ '__/ __| | |_) | __/ (_| | | | | | | | | __/ | \__ \ |____/ \___|\__, |_|_| |_|_| |_|\___|_| |___/ __/ | |___/ _____ _ _ | __ \ | | | | | |__) | _| |_| |__ ___ _ __ | ___/ | | | __| '_ \ / _ \| '_ \ | | | |_| | |_| | | | (_) | | | | |_| \__, |\__|_| |_|\___/|_| |_| __/ | |___/ """, getSampleStyleSheet()["Code"])) doc.build(story, onFirstPage=number_page, onLaterPages=number_page)
def print_vouchers(self): buffer = self.buffer styles = self.styles doc = SimpleDocTemplate(buffer, rightMargin=15 * mm, leftMargin=15 * mm, topMargin=0 * mm, bottomMargin=15 * mm, pagesize=self.pagesize) # Our container for 'Flowable' objects elements = [] for i, voucher in enumerate(self.vouchers): #qrcode = QRFlowable('http://redirect.wlan.tuerantuer.org/?voucher=' + voucher) #elements.append(qrcode) #elements.append(Paragraph('1. Deaktiviere deine mobilen Daten 2. Scannen 3. Du wirst eingeloggt!', styles['Voucher_Subtitle'])) elements.append(Spacer(0, 40 * mm)) self.print_table(elements, voucher) elements.append(Spacer(0, 10 * mm)) elements.append( ListFlowable([ ListItem(Paragraph( 'Verbinden Sie sich mit dem WLAN-Netzwerk (z.B. "net2otto", "net2wind"...)', styles['Text']), value='circle'), ListItem(Paragraph( 'Öffnen Sie ihren Webbrowser (Firefox, Chrome, Internet Explorer...)', styles['Text']), value='circle'), ListItem(Paragraph('Öffnen Sie eine beliebige Website', styles['Text']), value='circle'), ListItem(Paragraph('Die folgende Seite wird angezeigt:', styles['Text']), value='circle') ], style=styles['list_default'])) elements.append(Spacer(0, 2 * mm)) im = Image('assets/images/example.png') im._restrictSize(50 * mm, 50 * mm) elements.append(im) elements.append(Spacer(0, 2 * mm)) elements.append( ListFlowable([ ListItem(Paragraph( 'Geben Sie ihren persönlichen Voucher Code ein (Groß-/Kleinschreibung ist wichtig)', styles['Text']), value='circle'), ListItem(Paragraph('Klicken Sie auf "Submit"', styles['Text']), value='circle'), ListItem(Paragraph( 'Die Internetverbindung funktioniert jetzt.', styles['Text']), value='circle') ], style=styles['list_default'])) elements.append(Spacer(0, 10 * mm)) elements.append( Paragraph( ''' <b>Geben Sie den Voucher Code nicht weiter! Sie können das Internet nicht mehr normal Nutzen, falls jemand anderes Ihren Voucher Code kennt!</b> ''', styles["Text"])) elements.append(Spacer(0, 5 * mm)) elements.append( Paragraph( ''' Sie können den Voucher Code für mehrere Geräte benutzen, allerdings nur für maximal ein Gerät gleichzeitig. ''', styles["Text"])) elements.append(Spacer(0, 5 * mm)) elements.append( Paragraph( ''' <b>Erinnern Sie sich immer daran</b>, dass der Internetverkehr vom Internetanbieter protokolliert wird. Sie sind verantwortlich für jeglichen Missbrauch. Verstöße werden nach deutschem Gesetz verfolgt. ''', styles["Text"])) elements.append(PageBreak()) doc.build(elements, onFirstPage=self._header_footer, onLaterPages=self._header_footer)
def test1(self): if rl_invariant: random.seed(888147853) styleSheet = getSampleStyleSheet() doc = SimpleDocTemplate(outputfile('test_platypus_lists1.pdf'), showBoundary=True) story = [] sty = [ ('GRID', (0, 0), (-1, -1), 1, colors.green), ('BOX', (0, 0), (-1, -1), 2, colors.red), ] normal = styleSheet['BodyText'] bold = normal.clone('bold', fontName='Helvetica-Bold') lpSty = normal.clone('lpSty', spaceAfter=18) data = [[ str(i + 1), Paragraph("xx " * (i % 10), styleSheet["BodyText"]), Paragraph(("blah " * (i % 40)), normal) ] for i in range(5)] data1 = [[ str(i + 1), Paragraph(["zz ", "yy "][i] * (i + 3), styleSheet["BodyText"]), Paragraph(("duh " * (i + 3)), normal) ] for i in range(2)] OL = ListFlowable([ Paragraph("A table with 5 rows", lpSty), Table(data, style=sty, colWidths=[50, 100, 200]), ListItem( Paragraph("A sublist", normal), value=7, ), ListFlowable( [ Paragraph("Another table with 3 rows", normal), Table(data[:3], style=sty, colWidths=[60, 90, 180]), Paragraph(TEXTS[0], normal), ], bulletType='i', ), Paragraph("An unordered sublist", normal), ListFlowable( [ Paragraph("A table with 2 rows", normal), ListItem(Table(data1, style=sty, colWidths=[60, 90, 180]), bulletColor='green'), ListItem(Paragraph(TEXTS[2], normal), bulletColor='red', value='square') ], bulletType='bullet', start='circle', ), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append(PageBreak()) story.append( Paragraph( "Now try a list with a very long URL in it. Without splitting the long word it used to be that this can push out the right page margin", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( '''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: <a href="http://www.biometricassociates.com/downloads/user-guides/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf" color="blue">http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf</a>.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append( Paragraph( "Same as above with a simple paragraph for the long word", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( '''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append( Paragraph( "Same as above with a simple unicode paragraph for the long word", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( u'''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append( ListFlowable( [ Paragraph("Level 0.1", normal), Paragraph("Level 0.2", normal), ListFlowable([ Paragraph("Level 1.1", normal), Paragraph("Level 1.1", normal), ListFlowable([ Paragraph("Level 2.1", normal), Paragraph("Level 2.1", normal), Paragraph("Level 2.3", normal), ], ), Paragraph("Level 1.4", normal), ], ), Paragraph("Level 0.4", normal), ], bulletType='1', start='10', ), ) story.append(PageBreak()) story.append(Paragraph("DDIndenter", style=normal)) story.append(Paragraph("Coffee", style=bold)) story.append( DDIndenter(Paragraph("Black hot drink", style=normal), leftIndent=36)) story.append(Paragraph("Milk", style=bold)) story.append( DDIndenter(Paragraph("White cold drink", style=normal), leftIndent=36)) story.append(Paragraph("Whiskey", style=bold)) story.append( DDIndenter(Paragraph("A nice alcoholic drink", style=normal), leftIndent=36)) story.append(PageBreak()) story.append(Paragraph("MultiCol", style=normal)) RT = 'STARTUP COMPUTERS BLAH BUZZWORD STARTREK PRINTING PYTHON CHOMSKY CHOMSKY'.split( ) for i in range(5): topic = RT[randint(0, len(RT) - 1)] np = randint(2, 6) story.append( MultiCol( [[Paragraph('Column %d' % (i + 1, ), style=bold)], [], [ Paragraph(xmlEscape( randomtext.randomText(topic, randint(1, 7))), style=normal) for j in range(np) ]], widths=['20%', 3, '80%'], )) story.append(PageBreak()) story.append(Paragraph("MultiCol 2", style=normal)) for i in range(5): topic = RT[randint(0, len(RT) - 1)] np = randint(2, 6) story.append( MultiCol( [([Paragraph('Column %d' % (i + 1, ), style=bold)] + [ Paragraph(xmlEscape( randomtext.randomText(topic, randint(1, 7))), style=normal) for j in range(np) ]), [], [ Paragraph(xmlEscape( randomtext.randomText(topic, randint(1, 7))), style=normal) for j in range(np) ]], widths=['50%', 5, '50%'], )) doc.build(story)
from reportlab.platypus import ListFlowable, ListItem from reportlab.platypus.flowables import DocPara, DocAssign from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import Paragraph, SimpleDocTemplate, Frame from reportlab.lib.pagesizes import A4, inch from reportlab.pdfgen.canvas import Canvas styles = getSampleStyleSheet() style = styles["Normal"] story = [] # bulletType = a/i/a/A/ I t = ListFlowable([ Paragraph("Item no.1 company_name", style), ListItem(Paragraph("Item no. 2", style), bulletColor="green", value=7), ListFlowable( [ Paragraph("sublist item 1", style), ListItem(Paragraph('sublist item 2', style), bulletColor='red', value='square'), ListItem(Paragraph('sublist item 2', style), bulletColor='red', value='square') ], bulletType='bullet', start='square', ), Paragraph("Item no.4", style) ], bulletType='i') story.append(Paragraph("Hello World", style))
def _create_approval_cols(approval_buffer, approval, proposal, copied_to_permit, user): site_url = settings.SITE_URL every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 160, id='EveryPagesFrame') every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame], onPage=_create_approval_header) doc = BaseDocTemplate(approval_buffer, pageTemplates=[every_page_template], pagesize=A4) # this is the only way to get data into the onPage callback function doc.approval = approval doc.site_url = site_url approval_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')]) box_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'), ('BOX', (0, 0), (-1, -1), 0.25, black), ('INNERGRID', (0, 0), (-1, -1), 0.25, black), ('ALIGN', (0, 0), (-1, -1), 'RIGHT')]) elements = [] #Organization details address = proposal.applicant_address # address = proposal.applicant_address if proposal.org_applicant: try: email = proposal.org_applicant.organisation.organisation_set.all( ).first().contacts.all().first().email except: raise ValidationError( 'There is no contact for Organisation. Please create an Organisation contact' ) else: email = proposal.submitter.email #elements.append(Paragraph(email,styles['BoldLeft'])) elements.append( Paragraph('CONSERVATION AND LAND MANAGEMENT REGULATIONS 2002 (PART 7)', styles['ItalicCenter'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph('COMMERCIAL OPERATIONS LICENCE', styles['InfoTitleVeryLargeCenter'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph( 'The Chief Executive Officer (CEO) of the Department of Biodiversity, Conservation and Attractions hereby grants a commercial operations licence to enter upon and conduct activities within the parks/reserves listed in Schedule 1 of this licence to:', styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # delegation holds the Licence number and applicant name in table format. delegation = [] delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Table( [[[Paragraph('Licensee:', styles['BoldLeft'])], [Paragraph(_format_name(approval.applicant), styles['Left'])]]], colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), style=approval_table_style)) if approval.current_proposal.org_applicant and approval.current_proposal.org_applicant.organisation.trading_name: delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Table([[[Paragraph('Trading Name:', styles['BoldLeft'])], [ Paragraph( _format_name( approval.current_proposal.org_applicant. organisation.trading_name), styles['Left']) ]]], colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), style=approval_table_style)) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Table([[[Paragraph('Licence Number:', styles['BoldLeft'])], [Paragraph(approval.lodgement_number, styles['Left'])]]], colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), style=approval_table_style)) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(KeepTogether(delegation)) elements.append( Paragraph( 'Commencing on the {} and expiring on {}.'.format( approval.start_date.strftime(DATE_FORMAT2), approval.expiry_date.strftime(DATE_FORMAT2)), styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Paragraph('CONDITIONS', styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) list_of_bullets = [] list_of_bullets.append( 'This Commercial Operations Licence is subject to the provisions of the <i>Conservation and Land Management Act 1984</i> and all subsidiary legislation made under it.' ) list_of_bullets.append( 'The Licensee must comply with and not contravene the conditions and restrictions set out in the Commercial Operator Handbook as varied from time to time by the CEO.' ) list_of_bullets.append( 'The Licensee must comply with the conditions contained in any schedule of conditions attached to this Commercial Operations Licence.' ) understandingList = ListFlowable([ ListItem(Paragraph(a, styles['Left']), bulletColour='black') for a in list_of_bullets ], bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE) #bulletFontName=BOLD_FONTNAME elements.append(understandingList) elements += _layout_extracted_fields(approval.extracted_fields) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph('{} {}'.format(user.first_name, user.last_name), styles['Left'])) if user.position_title: elements.append( Paragraph('{}'.format(user.position_title), styles['Left'])) elements.append(Paragraph('As Delegate of CEO', styles['Left'])) elements.append( Paragraph('Under Section 133(2) of the CALM Act 1984', styles['Left'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['Left'])) elements.append(PageBreak()) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) table_data = [ [ Paragraph('Licence Number', styles['BoldLeft']), Paragraph(_format_name(approval.lodgement_number), styles['Left']) ], [ Paragraph('Commencement Date', styles['BoldLeft']), Paragraph( _format_name(approval.start_date).strftime(DATE_FORMAT), styles['Left']) ], [ Paragraph('Expiry Date', styles['BoldLeft']), Paragraph( _format_name(approval.expiry_date).strftime(DATE_FORMAT), styles['Left']) ] ] t = Table(table_data, colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), style=box_table_style) elements.append(t) # Schedule 1 elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Paragraph('SCHEDULE 1', styles['BoldCenter'])) elements.append( Paragraph('COMMERCIAL OPERATIONS LICENCE ACTIVITIES', styles['BoldCenter'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) park_data = [] for p in approval.current_proposal.selected_parks_activities_pdf: activities_str = [] for ac in p['activities']: activities_str.append(ac.encode('UTF-8')) access_types_str = [] if 'access_types' in p: for at in p['access_types']: access_types_str.append(at.encode('UTF-8')) activities_str = str(activities_str).strip('[]').replace('\'', '') access_types_str = str(access_types_str).strip('[]').replace('\'', '') activities_str = activities_str if access_types_str == '' else access_types_str + ', ' + activities_str park_data.append([ Paragraph(_format_name(p['park']), styles['BoldLeft']), Paragraph(activities_str.strip().strip(','), styles['Left']) # remove last trailing comma ]) if park_data: t = Table(park_data, colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), style=box_table_style) elements.append(t) # Schedule 2 elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Paragraph('SCHEDULE 2', styles['BoldCenter'])) elements.append( Paragraph('COMMERCIAL OPERATIONS LICENCE CONDITIONS', styles['BoldCenter'])) requirements = proposal.requirements.all().exclude(is_deleted=True) if requirements.exists(): elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) #elements.append(Paragraph('The following requirements must be satisfied for the licence not to be withdrawn:', styles['BoldLeft'])) #elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) conditionList = ListFlowable([ Paragraph(a.requirement, styles['Left']) for a in requirements.order_by('order') ], bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE) elements.append(conditionList) doc.build(elements) return approval_buffer
def test1(self): styleSheet = getSampleStyleSheet() doc = SimpleDocTemplate(outputfile('test_platypus_lists1.pdf')) story = [] sty = [ ('GRID', (0, 0), (-1, -1), 1, colors.green), ('BOX', (0, 0), (-1, -1), 2, colors.red), ] normal = styleSheet['BodyText'] lpSty = normal.clone('lpSty', spaceAfter=18) data = [[ str(i + 1), Paragraph("xx " * (i % 10), styleSheet["BodyText"]), Paragraph(("blah " * (i % 40)), normal) ] for i in range(5)] data1 = [[ str(i + 1), Paragraph(["zz ", "yy "][i] * (i + 3), styleSheet["BodyText"]), Paragraph(("duh " * (i + 3)), normal) ] for i in range(2)] OL = ListFlowable([ Paragraph("A table with 5 rows", lpSty), Table(data, style=sty, colWidths=[50, 100, 200]), ListItem( Paragraph("A sublist", normal), value=7, ), ListFlowable( [ Paragraph("Another table with 3 rows", normal), Table(data[:3], style=sty, colWidths=[60, 90, 180]), Paragraph(TEXTS[0], normal), ], bulletType='i', ), Paragraph("An unordered sublist", normal), ListFlowable( [ Paragraph("A table with 2 rows", normal), ListItem(Table(data1, style=sty, colWidths=[60, 90, 180]), bulletColor='green'), ListItem(Paragraph(TEXTS[2], normal), bulletColor='red', value='square') ], bulletType='bullet', start='circle', ), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append(PageBreak()) story.append( Paragraph( "Now try a list with a very long URL in it. Without splitting the long word it used to be that this can push out the right page margin", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( '''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: <a href="http://www.biometricassociates.com/downloads/user-guides/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf" color="blue">http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf</a>.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append( Paragraph( "Same as above with a simple paragraph for the long word", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( '''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) story.append( Paragraph( "Same as above with a simple unicode paragraph for the long word", normal)) OL = ListFlowable([ Paragraph(TEXTS[1], normal), Paragraph( u'''For details about pairing the smart card reader with the Android device, refer to the baiMobile specification: http://www.biometricassociates.com/downloads/user-guides/make-the-url-even-longer/baiMobile-3000MP-User-Guide-for-Android-v2.0.pdf.''', normal), Paragraph(TEXTS[1], normal), ]) story.append(OL) doc.build(story)
def _create_approval(approval_buffer, approval, proposal, copied_to_permit, user): site_url = settings.SITE_URL every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN, PAGE_HEIGHT - 160, id='EveryPagesFrame') every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame], onPage=_create_approval_header) doc = BaseDocTemplate(approval_buffer, pageTemplates=[every_page_template], pagesize=A4) # this is the only way to get data into the onPage callback function doc.approval = approval doc.site_url = site_url region = approval.region if hasattr(approval, 'region') else '' district = approval.district if hasattr(approval, 'district') else '' region_district = '{} - {}'.format(region, district) if district else region approval_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')]) elements = [] title = approval.title.encode('UTF-8') #Organization details address = proposal.applicant.organisation.postal_address email = proposal.applicant.organisation.organisation_set.all().first( ).contacts.all().first().email elements.append(Paragraph(email, styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph(_format_name(approval.applicant), styles['BoldLeft'])) elements.append(Paragraph(address.line1, styles['BoldLeft'])) elements.append(Paragraph(address.line2, styles['BoldLeft'])) elements.append(Paragraph(address.line3, styles['BoldLeft'])) elements.append( Paragraph( '%s %s %s' % (address.locality, address.state, address.postcode), styles['BoldLeft'])) elements.append(Paragraph(address.country.name, styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) #elements.append(Paragraph(title, styles['InfoTitleVeryLargeCenter'])) #elements.append(Paragraph(approval.activity, styles['InfoTitleLargeLeft'])) elements.append( Paragraph( 'APPROVAL OF PROPOSAL {} {} TO UNDERTAKE DISTURBANCE ACTIVITY IN {}' .format(title, proposal.lodgement_number, region_district), styles['InfoTitleLargeLeft'])) #import ipdb; ipdb.set_trace() #elements.append(Paragraph(approval.tenure if hasattr(approval, 'tenure') else '', styles['InfoTitleLargeRight'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph( 'The submitted proposal {} {} has been assessed and approved. The approval is granted on the understanding that: ' .format(title, proposal.lodgement_number), styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) list_of_bullets = [] list_of_bullets.append( 'The potential impacts of the proposal on values the department manages have been removed or minimised to a level \'As Low As Reasonably Practicable\' (ALARP) and the proposal is consistent with departmental objectives, associated management plans and the land use category/s in the activity area.' ) list_of_bullets.append( 'Approval is granted for the period {} to {}. This approval is not valid if {} makes changes to what has been proposed or the proposal has expired. To change the proposal or seek an extension, the proponent must re-submit the proposal for assessment.' .format(approval.start_date.strftime(DATE_FORMAT), approval.expiry_date.strftime(DATE_FORMAT), _format_name(approval.applicant))) list_of_bullets.append( 'The proponent accepts responsibility for advising {} of new information or unforeseen threats that may affect the risk of the proposed activity.' .format(settings.DEP_NAME_SHORT)) list_of_bullets.append( 'Information provided by {0} for the purposes of this proposal will not be provided to third parties without permission from {0}.' .format(settings.DEP_NAME_SHORT)) list_of_bullets.append( 'The proponent accepts responsibility for supervising and monitoring implementation of activity/ies to ensure compliance with this proposal. {} reserves the right to request documents and records demonstrating compliance for departmental monitoring and auditing.' .format(settings.DEP_NAME_SHORT)) list_of_bullets.append( 'Non-compliance with the conditions of the proposal may trigger a suspension or withdrawal of the approval for this activity.' ) list_of_bullets.append( 'Management actions listed in Appendix 1 are implemented.') understandingList = ListFlowable([ ListItem( Paragraph(a, styles['Left']), bulletColour='black', value='circle') for a in list_of_bullets ], bulletFontName=BOLD_FONTNAME, bulletFontSize=SMALL_FONTSIZE, bulletType='bullet') #bulletFontName=BOLD_FONTNAME elements.append(understandingList) # proposal requirements requirements = proposal.requirements.all().exclude(is_deleted=True) if requirements.exists(): elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append( Paragraph( 'The following requirements must be satisfied for the approval of the proposal not to be withdrawn:', styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) conditionList = ListFlowable([ Paragraph(a.requirement, styles['Left']) for a in requirements.order_by('order') ], bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE) elements.append(conditionList) # if copied_to_permit: # elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # elements.append(Paragraph('Assessor Comments', styles['BoldLeft'])) # elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # for k,v in copied_to_permit: # elements.append(Paragraph(v.encode('UTF-8'), styles['Left'])) # elements.append(Paragraph(k.encode('UTF-8'), styles['Left'])) # elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements += _layout_extracted_fields(approval.extracted_fields) # additional information '''if approval.additional_information: elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) elements.append(Paragraph('Additional Information', styles['BoldLeft'])) elements += _layout_paragraphs(approval.additional_information)''' # delegation holds the dates, approvale and issuer details. delegation = [] # dates and licensing officer # dates_licensing_officer_table_style = TableStyle([('VALIGN', (0, 0), (-2, -1), 'TOP'), # ('VALIGN', (0, 0), (-1, -1), 'BOTTOM')]) # delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # date_headings = [Paragraph('Date of Issue', styles['BoldLeft']), Paragraph('Valid From', styles['BoldLeft']), # Paragraph('Date of Expiry', styles['BoldLeft'])] # date_values = [Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['Left']), # Paragraph(approval.start_date.strftime(DATE_FORMAT), styles['Left']), # Paragraph(approval.expiry_date.strftime(DATE_FORMAT), styles['Left'])] # if approval.original_issue_date is not None: # date_headings.insert(0, Paragraph('Original Date of Issue', styles['BoldLeft'])) # date_values.insert(0, Paragraph(approval.original_issue_date.strftime(DATE_FORMAT), styles['Left'])) # delegation.append(Table([[date_headings, date_values]], # colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), # style=dates_licensing_officer_table_style)) # proponent details # delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) # address = proposal.applicant.organisation.postal_address # address_paragraphs = [Paragraph(address.line1, styles['Left']), Paragraph(address.line2, styles['Left']), # Paragraph(address.line3, styles['Left']), # Paragraph('%s %s %s' % (address.locality, address.state, address.postcode), styles['Left']), # Paragraph(address.country.name, styles['Left'])] # delegation.append(Table([[[Paragraph('Licensee:', styles['BoldLeft']), Paragraph('Address', styles['BoldLeft'])], # [Paragraph(_format_name(approval.applicant), # styles['Left'])] + address_paragraphs]], # colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120), # style=approval_table_style)) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Paragraph( 'Should you have any queries about this approval, please contact {} {}, ' 'on {} or by email at {}'.format(user.first_name, user.last_name, settings.DEP_PHONE, user.email), styles['Left'])) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Paragraph( 'To provide feedback on the system used to submit the approval or update contact details, please ' 'contact {} Works Coordinator - {}'.format( settings.SYSTEM_NAME_SHORT, settings.SUPPORT_EMAIL), styles['Left'])) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append(Paragraph('Approved on behalf of the', styles['Left'])) delegation.append( Paragraph('{}'.format(settings.DEP_NAME), styles['BoldLeft'])) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Paragraph('{} {}'.format(user.first_name, user.last_name), styles['Left'])) delegation.append(Paragraph('{}'.format(region_district), styles['Left'])) delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT)) delegation.append( Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['Left'])) elements.append(KeepTogether(delegation)) # Appendix section elements.append(PageBreak()) elements.append( Paragraph('Appendix 1 - Management Actions', styles['BoldLeft'])) elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) if copied_to_permit: # for k,v in copied_to_permit: # elements.append(Paragraph(v.encode('UTF-8'), styles['Left'])) # elements.append(Paragraph(k.encode('UTF-8'), styles['Left'])) # elements.append(Spacer(1, SECTION_BUFFER_HEIGHT)) for item in copied_to_permit: for key in item: elements.append(Paragraph(key.encode('UTF-8'), styles['Left'])) elements.append( Paragraph(item[key].encode('UTF-8'), styles['Left'])) else: elements.append( Paragraph('There are no management actions.', styles['Left'])) doc.build(elements) return approval_buffer
def render_workout_day(day, nr_of_weeks=7, images=False, comments=False, only_table=False): """ Render a table with reportlab with the contents of the training day :param day: a workout day object :param nr_of_weeks: the numbrer of weeks to render, default is 7 :param images: boolean indicating whether to also draw exercise images in the PDF (actually only the main image) :param comments: boolean indicathing whether the exercise comments will be rendered as well :param only_table: boolean indicating whether to draw a table with space for weight logs or just a list of the exercises """ # If rendering only the table, reset the nr of weeks, since these columns # will not be rendered anyway. if only_table: nr_of_weeks = 0 data = [] # Init some counters and markers, this will be used after the iteration to # set different borders and colours day_markers = [] group_exercise_marker = {} set_count = 1 day_markers.append(len(data)) p = Paragraph('<para align="center">%(days)s: %(description)s</para>' % {'days': day['days_of_week']['text'], 'description': day['obj'].description}, styleSheet["SubHeader"]) data.append([p]) # Note: the _('Date') will be on the 3rd cell, but since we make a span # over 3 cells, the value has to be on the 1st one data.append([_('Date') + ' ', '', ''] + [''] * nr_of_weeks) data.append([_('Nr.'), _('Exercise'), _('Reps')] + [_('Weight')] * nr_of_weeks) # Sets exercise_start = len(data) for set in day['set_list']: group_exercise_marker[set['obj'].id] = {'start': len(data), 'end': len(data)} # Exercises for exercise in set['exercise_list']: group_exercise_marker[set['obj'].id]['end'] = len(data) # Process the settings if exercise['has_weight']: setting_out = [] for i in exercise['setting_text'].split('–'): setting_out.append(Paragraph(i, styleSheet["Small"], bulletText='')) else: setting_out = Paragraph(exercise['setting_text'], styleSheet["Small"]) # Collect a list of the exercise comments item_list = [Paragraph('', styleSheet["Small"])] if comments: item_list = [ListItem(Paragraph(i, style=styleSheet["ExerciseComments"])) for i in exercise['comment_list']] # Add the exercise's main image image = Paragraph('', styleSheet["Small"]) if images: if exercise['obj'].main_image: # Make the images somewhat larger when printing only the workout and not # also the columns for weight logs if only_table: image_size = 2 else: image_size = 1.5 image = Image(exercise['obj'].main_image.image) image.drawHeight = image_size * cm * image.drawHeight / image.drawWidth image.drawWidth = image_size * cm # Put the name and images and comments together exercise_content = [Paragraph(exercise['obj'].name, styleSheet["Small"]), image, ListFlowable(item_list, bulletType='bullet', leftIndent=5, spaceBefore=7, bulletOffsetY=-3, bulletFontSize=3, start='square')] data.append([f"#{set_count}", exercise_content, setting_out] + [''] * nr_of_weeks) set_count += 1 table_style = [('FONT', (0, 0), (-1, -1), 'OpenSans'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('LEFTPADDING', (0, 0), (-1, -1), 2), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (-1, -1), 3), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black), # Header ('BACKGROUND', (0, 0), (-1, 0), header_colour), ('BOX', (0, 0), (-1, -1), 1.25, colors.black), ('BOX', (0, 1), (-1, -1), 1.25, colors.black), ('SPAN', (0, 0), (-1, 0)), # Cell with 'date' ('SPAN', (0, 1), (2, 1)), ('ALIGN', (0, 1), (2, 1), 'RIGHT')] # Combine the cells for exercises on the same superset for marker in group_exercise_marker: start_marker = group_exercise_marker[marker]['start'] end_marker = group_exercise_marker[marker]['end'] table_style.append(('VALIGN', (0, start_marker), (0, end_marker), 'MIDDLE')) table_style.append(('SPAN', (0, start_marker), (0, end_marker))) # Set an alternating background colour for rows with exercises. # The rows with exercises range from exercise_start till the end of the data # list for i in range(exercise_start, len(data) + 1): if not i % 2: table_style.append(('BACKGROUND', (0, i - 1), (-1, i - 1), row_color)) # Put everything together and manually set some of the widths t = Table(data, style=table_style) if len(t._argW) > 1: if only_table: t._argW[0] = 0.6 * cm # Numbering t._argW[1] = 8 * cm # Exercise t._argW[2] = 3.5 * cm # Repetitions else: t._argW[0] = 0.6 * cm # Numbering t._argW[1] = 4 * cm # Exercise t._argW[2] = 3 * cm # Repetitions return KeepTogether(t)
def format_answer(self, text, answer_type): return ListItem(Paragraph(text, self.answers_style), value=answer_type, leftIndent=60)