def test_06_fontsize(self): from reportlab.lib.pagesizes import A4 from reportlab.pdfgen.canvas import Canvas from reportlab.lib.units import inch from reportlab.lib.colors import red, magenta c = Canvas('demo.pdf', pagesize=A4) c.translate(inch, inch) c.setFont("Times-Roman", 20) c.setFillColor(red) c.saveState() c.drawCentredString(2.75 * inch, 2.5 * inch, "Font size excmples") c.setFillColor(magenta) size = 7 x = 2.3 * inch y = 1.3 * inch for line in range(7): c.setFont("Helvetica", size) c.drawRightString(x, y, "%s points" % size) c.drawString(x, y, "test") y = y - size * 1.2 size = size + 1.5 c.restoreState() c.drawString(0, 0, "%s" % c.getAvailableFonts()) c.showPage() c.save()
def projects(c: canvas.Canvas, info: dict, top: float, theme: dict): #header - left - red - line below c.setFont("Helvetica-Bold", 12) setColor(c, theme['accent']) top -= MARGIN / 4 c.drawString(MARGIN, top, "Projects") top -= inch / 12 c.line(MARGIN, top, WIDTH - MARGIN, top) #each project top -= inch / 6 for project in info["Projects"]: #title setColor(c, theme['front']) c.setFont("Helvetica-Bold", 10) c.drawString(MARGIN + inch / 4, top, project["name"]) #link c.setFont("Helvetica-Oblique", 9) setColor(c, theme['accent']) c.drawRightString(WIDTH - MARGIN, top, project["link"]) x1 = WIDTH - MARGIN - c.stringWidth(project["link"]) x2 = WIDTH - MARGIN c.linkURL("https://" + project["link"], (x1, top, x2, top + 9)) #description c.setFont("Helvetica", 9) setColor(c, theme['front']) for line in project["description"]: top -= inch / 6 c.drawString(MARGIN + inch / 3, top, "• " + line) top -= inch / 6 return top + inch / 20
def test_06_fontsize(self): from reportlab.lib.pagesizes import A4 from reportlab.pdfgen.canvas import Canvas from reportlab.lib.units import inch from reportlab.lib.colors import red, magenta c = Canvas('demo.pdf', pagesize=A4) c.translate(inch, inch) c.setFont("Times-Roman", 20) c.setFillColor(red) c.saveState() c.drawCentredString(2.75*inch, 2.5*inch,"Font size excmples") c.setFillColor(magenta) size = 7 x = 2.3 * inch y = 1.3 * inch for line in range(7): c.setFont("Helvetica", size) c.drawRightString(x, y, "%s points" % size) c.drawString(x,y, "test") y = y-size*1.2 size = size+1.5 c.restoreState() c.drawString(0,0, "%s" % c.getAvailableFonts()) c.showPage() c.save()
def education(c: canvas.Canvas, info: dict, top: float, theme: dict): #header - left - red - line below c.setFont("Helvetica-Bold", 12) setColor(c, theme['accent']) top -= MARGIN / 4 c.drawString(MARGIN, top, "Education") top -= inch / 12 c.line(MARGIN, top, WIDTH - MARGIN, top) #university name - bold, black top -= inch / 6 setColor(c, theme['front']) c.setFont("Helvetica-Bold", 10) c.drawString(MARGIN + inch / 4, top, info["Education"]["school"]) #expected grad - bold c.drawRightString( WIDTH - MARGIN, top, "Expected Graduation: " + info["Education"]["graduation"]) #major, gpa - small c.setFont("Helvetica", 9) top -= inch / 6 c.drawString( MARGIN + inch / 3, top, info["Education"]["degree"] + " | " + info["Education"]["gpa"]) return top - inch / 12
def add_footer(): input_file = "/tmp/merged.pdf" output_file = "/tmp/merged_footer.pdf" # Get pages reader = PdfReader(input_file) pages = [pagexobj(p) for p in reader.pages] # Compose new pdf canvas = Canvas(output_file) for page_num, page in enumerate(pages, start=1): # # Add page canvas.setPageSize((page.BBox[2], page.BBox[3])) canvas.doForm(makerl(canvas, page)) canvas.setFont("Helvetica", 10) if canvas._pagesize[0] > canvas._pagesize[1]: canvas.saveState() canvas.rotate(270) canvas.translate(-30, -A4[0] + 30) canvas.drawRightString( -10, A4[0], "%d de %d" % (canvas._pageNumber, len(pages))) canvas.restoreState() else: canvas.drawRightString( A4[0] - 60, 30, "%d de %d" % (canvas._pageNumber, len(pages))) canvas.showPage() canvas.save()
def generateOfficePDF(self,response): #Attach name.pdf file to responses content disposition response['Content-Disposition'] = 'attachment; filename=office.pdf' #Create empty pdf document, hook pdf with response pdf = Canvas(response) #Get Todays Events brains = sorted(util.gatherTodaysEvents(self), key=attrgetter('location')) #so awesome, sorts on any attribute! brains = sorted(brains, key=attrgetter('start')) #even better a secondary sort. #Header: Title Information and Settings pdf.setFont("Helvetica-Bold", 12) pdf.setStrokeColorRGB(0, 0, 0) #sets Line/Rectangle Colors #Header Left Title if brains != None and len(brains) > 0: pdf.drawString(15, 810, DateTime(brains[0].start).strftime("%A, %B %d, %Y") + " Schedule") else: pdf.drawString(15, 810, "No Groups scheduled for " + datetime.datetime.now().strftime("%A, %B %d, %Y")) #Header Right Title pdf.drawRightString(575, 810, "GroupFinder") #Body: List of Groups and Settings index = 792 #Pixel Index, starting at the top of the pdf page page = 1 #Page Number for brain in brains: pdf.setFont("Helvetica", 12) pdf.setStrokeColorRGB(0, 0, 0) #sets Line/Rectangle Colors pdf.rect(10, index-20, 575, 30, stroke=1, fill=0) #Rectangle around each Group pdf.drawString(15, index-3, brain.Title) #Group Description l = self.locationLookup(brain.location) pdf.drawString(15, index-15, DateTime(brain.start).strftime("%I:%M %p") + " - " + DateTime(brain.end).strftime("%I:%M %p") + " in " + l['Name']) index -= 30 #Move Pixel Index downwards #Reach Bottom of page? Creates New Page. if index < 30: pdf.drawString(15, 5, "Page " + str(page))#add page number pages pdf.drawCentredString(300, 5, "Created on " + datetime.datetime.now().strftime("%m/%d/%Y at %I:%M %p")) page+=1 index = 792 pdf.showPage() #next page #add page number pages pdf.drawString(15, 5, "Page " + str(page)) #add date PDF was created pdf.drawCentredString(300, 5, "Created on " + datetime.datetime.now().strftime("%m/%d/%Y at %I:%M %p")) pdf.showPage() #next page, finalize last page. pdf.save() #save the pdf content return response #return response with hooked pdf.
def _on_other_page(self, canvas: Canvas, doc): canvas.saveState() canvas.setFont('OpenSans', 8) canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page,)) for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip()) canvas.restoreState()
def pdf_demo_9(file): c = Canvas(file, pagesize=A4) x, y = 50 * mm, 280 * mm for font in c.getAvailableFonts(): c.setFont("Courier", 10) c.drawRightString(x - 5, y, font) c.setFont(font, 12) c.drawString(x + 5, y, "Quick brown fox jumped over the lazy dog") y -= 15 # Drop 15 point for each line c.setFont("Times-Italic", 10) c.drawCentredString(105 * mm, 10 * mm, "Page 1") c.save()
def header(c: canvas.Canvas, info: dict, theme: dict, top=HEIGHT - MARGIN) -> float: #smaller font, italic, red c.setFont("Helvetica-Oblique", 10) setColor(c, theme['accent']) #linkedin - left c.drawString(MARGIN, top, info["Info"]["linkedin"]) c.linkURL("https://" + info["Info"]["linkedin"], (MARGIN, top, MARGIN + c.stringWidth(info["Info"]["linkedin"]), top + 10)) #github - right c.drawRightString(WIDTH - MARGIN, HEIGHT - MARGIN, info["Info"]["github"]) c.linkURL("https://" + info["Info"]["github"], (WIDTH - MARGIN - c.stringWidth(info["Info"]["github"]) - 3, top, WIDTH - MARGIN, top + 10)) #name setColor(c, theme['front']) top -= inch / 3 c.setFont("Helvetica-Bold", 20) c.drawRightString(WIDTH / 2 - 2, top, info["Info"]["name"][0]) #first setColor(c, theme['accent']) c.drawString(WIDTH / 2 + 2, top, info["Info"]["name"][1]) #last x1 = WIDTH / 2 - c.stringWidth(info["Info"]["name"][0]) x2 = WIDTH / 2 + c.stringWidth(info["Info"]["name"][1]) c.linkURL("https://" + info["Info"]["site"], (x1, top, x2, top + 20)) #contact info - center below name top -= 20 #size of name setColor(c, theme['front']) c.setFont("Helvetica", 10) contact = info["Info"]["email"] + " | " + info["Info"][ "phone-number"] + " | " + info["Info"]["site"] c.drawCentredString(WIDTH / 2, top, contact) #link site x2 = (WIDTH + c.stringWidth(contact)) / 2 x1 = x2 - c.stringWidth(info["Info"]["site"]) c.linkURL("https://" + info["Info"]["site"], (x1, top, x2, top + 10)) #link email x1 = (WIDTH - c.stringWidth(contact)) / 2 x2 = x1 + c.stringWidth(info["Info"]["email"]) c.linkURL("mailto:" + info["Info"]["email"], (x1, top, x2, top + 10)) #canvas.drawRightString(x, y, theme['front']), drawString(x, y, theme['front']) return top - inch / 20
def certifications(c: canvas.Canvas, info: dict, top: float, theme: dict): #header - left - red - line below c.setFont("Helvetica-Bold", 12) setColor(c, theme['accent']) top -= MARGIN / 4 c.drawString(MARGIN, top, "Certifications") top -= inch / 12 c.line(MARGIN, top, WIDTH - MARGIN, top) setColor(c, theme['front']) for cert in info["Certifications"]: #certifier - bold, black top -= inch / 6 c.setFont("Helvetica-Bold", 10) c.drawString(MARGIN + inch / 4, top, cert["certifier"]) #list of certs - small c.setFont("Helvetica", 9) certs = ', '.join(cert["certifications"]) c.drawRightString(WIDTH - MARGIN, top, certs) return top - inch / 12
def experience(c: canvas.Canvas, info: dict, top: float, theme: dict): #header - left - red - line below c.setFont("Helvetica-Bold", 12) setColor(c, theme['accent']) top -= MARGIN / 4 c.drawString(MARGIN, top, "Experience") top -= inch / 12 c.line(MARGIN, top, WIDTH - MARGIN, top) #each xp top -= inch / 6 for xp in info["Experience"]: #position setColor(c, theme['front']) c.setFont("Helvetica-Bold", 10) c.drawString(MARGIN + inch / 4, top, xp["position"] + " ") #dates c.drawRightString(WIDTH - MARGIN, top, xp["start"] + "-" + xp["end"]) #company top -= inch / 6 c.setFont("Helvetica", 10) c.drawString(MARGIN + inch / 4, top, xp["company"]) #location c.setFont("Helvetica-Oblique", 9) c.drawRightString(WIDTH - MARGIN, top, xp["location"]) #description setColor(c, theme['front']) c.setFont("Helvetica", 9) for line in xp["description"]: top -= inch / 6 c.drawString(MARGIN + inch / 3, top, "• " + line) top -= inch / 6 return top + inch / 20 #pull back up a little
def pdfout(parse, outfl, enableComments, font, page): if page.name == "A4": c = Canvas(outfl, pagesize=A4) width, height = A4 else: c = Canvas(outfl, pagesize=letter) width, height = letter c.setFont('CourierPrime', 12) pgs = splitScriptText(parse, page, font, enableComments) if len(parse.titlePage) > 0: pdfTitlePage(c, parse, page, font) c.showPage() title = "UNTITLED" if "title" in parse.titlePage: title = " ".join(parse.titlePage["title"]).upper() for pgno in range(0, len(pgs)): c.setFont('CourierPrime', 12) if pgno > 0: c.drawRightString((page.width - page.marginRight) * inch, height - 0.5*inch, str(pgno+1)+".") c.drawString(page.marginLeft*inch, height - 0.5*inch, title) lineno = 0 for e in pgs[pgno]: processPDFLine(c, e[0], e[1], lineno, page, font, width, height) lineno = lineno + 1 c.showPage() c.save()
def skills(c: canvas.Canvas, info: dict, top: float, theme: dict) -> float: #header - left - red - line below c.setFont("Helvetica-Bold", 12) setColor(c, theme['accent']) top -= MARGIN / 4 c.drawString(MARGIN, top, "Skills") top -= inch / 12 c.line(MARGIN, top, WIDTH - MARGIN, top) #software development - black - bold top -= inch / 6 setColor(c, theme['front']) c.setFont("Helvetica-Bold", 11) c.drawString(MARGIN + inch / 4, top, "Software Development") #proficient top -= inch / 6 c.setFont("Helvetica", 9) c.drawString(MARGIN + inch / 2, top, "Proficient: ") skills = ", ".join(info["Skills"]["Software Development"]["Proficient"]) c.drawRightString(WIDTH - MARGIN, top, skills) #familiar top -= inch / 6 c.drawString(MARGIN + inch / 2, top, "Familiar: ") skills = ", ".join(info["Skills"]["Software Development"]["Familiar"]) c.drawRightString(WIDTH - MARGIN, top, skills) #other - black - bold top -= inch / 6 c.setFont("Helvetica-Bold", 11) c.drawString(MARGIN + inch / 4, top, "Other") #other skills list - small c.setFont("Helvetica", 9) skills = ", ".join(info["Skills"]["Other"]) c.drawRightString(WIDTH - MARGIN, top, skills) return top - inch / 20 #the new bottom
def print_direction(c: Canvas, n, dir: Napravleniya, format_a6: bool = False): xn, yn = 0, 0 if not format_a6: if n % 2 != 0: xn = 1 if n > 2: yn = 1 barcode = eanbc.Ean13BarcodeWidget(dir.pk + 460000000000, humanReadable=0, barHeight=17) bounds = barcode.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(width, height) d.add(barcode) paddingx = 15 ac = dir.is_all_confirm() canc = dir.cancel visit = dir.visit_date is not None if ac or canc or visit: c.saveState() c.setFillColorRGB(0, 0, 0, 0.2) c.rotate(45) if xn == 0 and yn == 1: ox = w / 2 + 40 * mm oy = h / 2 - 30 * mm elif xn == 0 and yn == 0: ox = w / 2 - 65 * mm oy = 13.5 * mm elif xn == 1 and yn == 0: ox = w - 95.75 * mm oy = 13.5 * mm - h / 4 else: ox = w + 9.25 * mm oy = h / 2 - 30 * mm - h / 4 c.setFont('OpenSansBold', 50) s = 'ОТМЕНЕНО' if ac: s = 'ИСПОЛНЕНО' elif visit: s = 'ПОСЕЩЕНО' c.drawString(ox, oy, s) c.restoreState() c.setFont('OpenSans', 10) c.drawCentredString(w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 5) + (h / 2) * yn, dir.hospital_short_title) c.setFont('OpenSans', 8) c.drawCentredString( w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 15) + (h / 2) * yn, "(%s. %s)" % (dir.hospital_address, dir.hospital_phones)) c.setFont('OpenSans', 14) c.drawCentredString( w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 30) + (h / 2) * yn, "Направление" + ("" if not dir.imported_from_rmis else " из РМИС")) renderPDF.draw(d, c, w / 2 - width + (w / 2 * xn) - paddingx / 3 - 5 * mm, (h / 2 - height - 57) + (h / 2) * yn) c.setFont('OpenSans', 20) c.drawString(paddingx + (w / 2 * xn), (h / 2 - height) + (h / 2) * yn - 57, "№ " + str(dir.pk)) # Номер направления c.setFont('OpenSans', 9) c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 70) + (h / 2) * yn, "Создано: " + strdate(dir.data_sozdaniya) + " " + strtime(dir.data_sozdaniya)[:5]) history_num = dir.history_num additional_num = dir.additional_num if history_num and len(history_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, "№ истории: " + history_num) elif additional_num and len(additional_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, f"({str(additional_num).strip()})") elif dir.client.number_poliklinika and len( dir.client.number_poliklinika) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, f"({str(dir.client.number_poliklinika).strip()})") if dir.history_num and len(dir.history_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, "№ истории: " + dir.history_num) c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 80) + (h / 2) * yn, "ФИО: " + dir.client.individual.fio()) c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 80) + (h / 2) * yn, "Пол: " + dir.client.individual.sex) c.drawRightString( w / 2 * (xn + 1) - paddingx, (h / 2 - height - 90) + (h / 2) * yn, "Д/р: {} ({})".format(dir.client.individual.bd(), dir.client.individual.age_s(direction=dir))) c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 90) + (h / 2) * yn, "{}: {}".format("ID" if dir.client.base.is_rmis else "Номер карты", dir.client.number_with_type())) diagnosis = dir.diagnos.strip()[:35] if not dir.imported_from_rmis: if diagnosis != "": c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, ("" if dir.vich_code == "" else ("Код: " + dir.vich_code + " ")) + "Диагноз (МКБ 10): " + ("не указан" if diagnosis == "-" else diagnosis), ) elif dir.vich_code != "": c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, "Код: " + dir.vich_code) if dir.istochnik_f: c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 110) + (h / 2) * yn, "Источник финансирования: " + dir.client.base.title + " - " + dir.istochnik_f.title) else: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 110) + (h / 2) * yn, "Источник финансирования: ") else: nds = 0 if diagnosis != "": c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, "Диагноз (МКБ 10): " + diagnosis) nds = 5 if dir.imported_org: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 105 - nds) + (h / 2) * yn, "Организация: " + dir.imported_org.title) issledovaniya = dir.issledovaniya_set.all() vid = [] has_descriptive = False has_doc_refferal = False need_qr_code = False for i in issledovaniya: rtp = i.research.reversed_type if rtp < -1: has_doc_refferal = True rt = { -2: 'Консультации', -3: 'Лечение', -4: 'Стоматология', -5: 'Стационар', -6: 'Микробиология', -9998: 'Морфология', -9: 'Формы', -11: 'Заявления', -12: 'Мониторинги', }[rtp] # if rtp == -6: # has_micro = True else: rt = i.research.podrazdeleniye.get_title() if rt not in vid: vid.append(rt) if i.research.podrazdeleniye and i.research.podrazdeleniye.p_type == Podrazdeleniya.PARACLINIC: has_descriptive = True if i.research.podrazdeleniye.can_has_pacs: need_qr_code = True c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 120) + (h / 2) * yn, "Вид: " + ", ".join(vid)) if dir.purpose: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 120) + (h / 2) * yn, "Цель: " + dir.get_purpose_display()) if dir.external_organization: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 134) + (h / 2) * yn, dir.external_organization.title) if dir.parent and dir.parent.research.is_hospital: c.setFont('OpenSansBold', 8) c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 129) + (h / 2) * yn, ("Стационар-" + str(dir.parent.napravleniye_id))) c.setFont('OpenSans', 9) styleSheet = getSampleStyleSheet() all_iss = issledovaniya.count() max_f = 9 min_f = 7 max_res = 36 max_off = max_f - min_f font_size = max_f - (max_off * (all_iss / max_res)) styleSheet["BodyText"].leading = font_size + 0.5 data = [] values = [] service_locations = {} n = 0 for v in issledovaniya: n += 1 service_location_title = "" if not v.service_location else v.service_location.title if service_location_title: if service_location_title not in service_locations: service_locations[service_location_title] = [] service_locations[service_location_title].append(n) values.append({ "title": v.research.get_title(), "full_title": v.research.title, "sw": v.research.sort_weight, "count": v.how_many, "comment": v.localization.title if v.localization else v.comment, "n": n, "g": -1 if not v.research.fractions_set.exists() else v.research.fractions_set.first().relation_id, "info": v.research.paraclinic_info, "hospital_department_replaced_title": v.hospital_department_replaced_title, }) one_sl = len(service_locations) <= 1 tw = w / 2 - paddingx * 2 m = 0 ns = {} if has_descriptive or has_doc_refferal: tmp = [ Paragraph( '<font face="OpenSansBold" size="8">%s</font>' % ("Исследование" if not has_doc_refferal else "Назначение"), styleSheet["BodyText"]), Paragraph('<font face="OpenSansBold" size="8">Информация</font>', styleSheet["BodyText"]), ] data.append(tmp) colWidths = [int(tw * 0.5), int(tw * 0.5)] values.sort(key=lambda l: l["full_title"]) for v in values: ns[v["n"]] = v["n"] tmp = [ Paragraph( '<font face="OpenSans" size="8">' + ("" if one_sl else "№{}: ".format(v["n"])) + xh.fix(v["full_title"]) + ("" if not v["comment"] else " <font face=\"OpenSans\" size=\"" + str(font_size * 0.8) + "\">[{}]</font>".format(v["comment"])) + ("" if not v["hospital_department_replaced_title"] else f"<br/>Направлен в: {v['hospital_department_replaced_title']}" ) + "</font>", styleSheet["BodyText"], ), Paragraph( '<font face="OpenSans" size="8">' + xh.fix(v["info"]) + "</font>", styleSheet["BodyText"]), ] data.append(tmp) m = 8 else: colWidths = [int(tw / 2), int(tw / 2)] c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 134) + (h / 2) * yn, "Назначения: ") c.setStrokeColorRGB(0, 0, 0) c.setLineWidth(1) values.sort(key=lambda l: (l["g"], l["sw"])) n_rows = int(len(values) / 2) normvars = [] c_cnt = nc_cnt = 0 for i in range(0, len(values) + 1): if (i + 1) % 2 == 0: nc_cnt += 1 if nc_cnt + n_rows < len(values): normvars.append(values[nc_cnt + n_rows]) else: normvars.append(values[c_cnt]) c_cnt += 1 p = Paginator(normvars, 2) n = 1 for pg_num in p.page_range: pg = p.page(pg_num) tmp = [] for obj in pg.object_list: ns[obj["n"]] = n tmp.append( Paragraph( '<font face="OpenSans" size="' + str(font_size) + '">' + ("" if one_sl else "№{}: ".format(n)) + obj["title"] + ("" if not obj["count"] or obj["count"] == 1 else " ({}шт.)".format(str(obj["count"]))) + ("" if not obj["comment"] else " <font face=\"OpenSans\" size=\"" + str(font_size * 0.8) + "\">[{}]</font>".format(obj["comment"])) + "</font>", styleSheet["BodyText"], )) n += 1 if len(pg.object_list) < 2: tmp.append( Paragraph( '<font face="OpenSans" size="' + str(font_size) + '"></font>', styleSheet["BodyText"])) data.append(tmp) t = Table(data, colWidths=colWidths) t.setStyle( TableStyle([ ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('TEXTCOLOR', (0, -1), (-1, -1), colors.black), ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black), ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('LEFTPADDING', (0, 0), (-1, -1), 4), ('TOPPADDING', (0, 0), (-1, -1), 0.5), ('RIGHTPADDING', (0, 0), (-1, -1), 2), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ])) t.canv = c wt, ht = t.wrap(0, 0) t.drawOn(c, paddingx + (w / 2 * xn), ((h / 2 - height - 138 + m) + (h / 2) * yn - ht)) c.setFont('OpenSans', 8) if not has_descriptive and not has_doc_refferal: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 10, "Всего назначено: " + str(len(issledovaniya))) if service_locations: n = 0 if has_descriptive or has_doc_refferal else 1 if one_sl: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, "Место: " + list(service_locations)[0]) else: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, "Места оказания услуг:") for title in service_locations: n += 1 c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, title + " – услуги " + ', '.join( map(lambda x: "№{}".format(ns[x]), service_locations[title])), ) if need_qr_code: qr_value = translit(dir.client.individual.fio(), 'ru', reversed=True) qr_code = qr.QrCodeWidget(qr_value) qr_code.barWidth = 70 qr_code.barHeight = 70 qr_code.qrVersion = 1 d = Drawing() d.add(qr_code) renderPDF.draw(d, c, paddingx + (w / 2 * xn) + 200, 32 + (h / 2) * yn) nn = 0 if not dir.imported_from_rmis: if dir.doc_who_create and dir.doc_who_create != dir.doc: nn = 9 c.drawString( paddingx + (w / 2 * xn), 13 + (h / 2) * yn, Truncator("Выписал: %s, %s" % (dir.doc_who_create.get_fio(), dir.doc_who_create.podrazdeleniye.title)).chars(63)) if dir.doc: c.drawString( paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn, "Отделение: " + Truncator(dir.get_doc_podrazdeleniye_title()).chars(50)) c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn, "Л/врач: " + dir.doc.get_fio()) else: c.drawString(paddingx + (w / 2 * xn), 31 + (h / 2) * yn + nn, "РМИС#" + dir.rmis_number) c.drawString(paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn, "Создал направление: " + dir.doc_who_create.get_fio()) c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn, dir.doc_who_create.podrazdeleniye.title) c.setFont('OpenSans', 7) c.setLineWidth(0.25)
c.translate(0, -leading) c.drawString(0, 0, text.next()) c.translate(0, -20*mm) c.drawString(-100*mm, 0, "Canvas.drawCentredString") c.translate(0, -leading) for i in range(2): c.translate(0, -leading) c.drawCentredString(0, 0, text.next()) c.translate(0, -20*mm) c.drawString(-100*mm, 0, "Canvas.drawRightString") c.translate(0, -leading) for i in range(2): c.translate(0, -leading) c.drawRightString(0, 0, text.next()) c.translate(0, -20*mm) c.drawString(-100*mm, 0, "Canvas.beginText (Text object)") c.translate(0, -leading*2) # Text objects are more efficient for anything more than simple labels textobject = c.beginText() textobject.setTextOrigin(0, 0) textobject.setFont("Times-Italic", 10) # supply text one line at a time: for i in range(6): textobject.textLine(text.next()) textobject.textLine()
can.setLineWidth(1) # nouvelle épaisseur des lignes can.ellipse( centreX - .5 * cm, centreY - .5 * cm, # petit cercle indiquant la centreX + .5 * cm, centreY + .5 * cm) # position du centre de la page # Quelques textes, avec polices, orientation et alignement divers : can.setFillColor("navy") # couleur des textes texteC = "Petite pluie abat grand vent." # texte à centrer can.setFont("Times-Bold", 18) can.drawCentredString(centreX, centreY, texteC) texteG = "Qui ne risque rien, n'a rien." # texte à aligner à gauche can.setFont("Helvetica", 18) can.drawString(centreX, centreY - 1 * cm, texteG) texteD = "La nuit porte conseil." # texte à aligner à droite can.setFont("Courier", 18) can.drawRightString(centreX, centreY - 2 * cm, texteD) texteV = "L'espoir fait vivre." # texte à disposer verticalement can.rotate(90) can.setFont("Times-Italic", 18) can.drawString(centreY + 1 * cm, -centreX, texteV) # ! inversion des coordonnées ! texteE = "L'exception confirme la règle" # texte à afficher en blanc can.rotate(-90) # retour à l'orientation horiz. can.setFont("Times-BoldItalic", 28) can.setFillColor("white") # nouvelle couleur des textes can.drawCentredString(centreX, 7 * cm, texteE) can.save() # Sauvegarde du résultat
class InvoiceDocument: """This class represents a pdf invoice. All units are in mm pdffilePath is the output pdf file invoiceData = [invoiceHeader, lesson1List, ..., lessonNList] invoiceHeader = [invoice_date, invoice_to, invoice_for, invoice_ref, n, amount] lesson1List = [date, tuition_ref, hours, rate, amount, reason1, money1, ..., reasonN, moneyN, "discount", money] """ def __init__(self, pdffilePath, invoiceData): self.pageHeight = A4[1] / mm # in mm, all units in mm self.pageWidth = A4[0] / mm self.lMargin = 20.0 self.rMargin = 20.0 self.tMargin = 30.0 self.bMargin = 30.0 #print("page size of A4 in mm: ", self.pageWidth, self.pageHeight) self.canvas = Canvas(pdffilePath, pagesize=A4) self.canvas.setTitle("Invoice for Maths tuition") self.title = "Invoice for Maths tuition" self.fontPathBase = "./fonts/%s.ttf" #print("Font: ", self.fontPathBase % "DejaVuSerif") pdfmetrics.registerFont( TTFont('DejaVu', self.fontPathBase % "DejaVuSerif")) pdfmetrics.registerFont( TTFont('DejaVu-Bold', self.fontPathBase % "DejaVuSerif-Bold")) pdfmetrics.registerFont( TTFont('DejaVu-Italics', self.fontPathBase % "DejaVuSerif-Italic")) self.tutorData = [ "Hannes Buchholzer", "3 April Close, Horsham, RH12 2LL", "07516-100218", "*****@*****.**" ] self.invoiceHeader = invoiceData.pop(0) self.invoiceData = invoiceData # translate coordinates x,y in mm from top left # into pixels from bottom right def coord(self, x, y, fromRight=False, fromBottom=False): cx = (self.pageWidth - x) * mm if fromRight else x * mm cy = y * mm if fromBottom else (self.pageHeight - y) * mm return (cx, cy) # translate a mm value into pixels. Works also for a list of mm values def trans(self, x): if isinstance(x, list): cx = list(range(len(x))) for i in range(len(x)): cx[i] = float(x[i]) * mm else: cx = float(x) * mm return cx # convert Money to String # x should be a money amount as integer and float # the output is a string with £ sign def cM2S(self, x): x = float(x) if x < 0.0: pre = "-" x = -x else: pre = "" s = pre + "£{0:4.2f}".format(x) #print("convertMoney2String: ", x, " ", s) return s # convert date to String # x should be a list of 3 integers # day, month, year def cD2S(self, x): if x[2] < 100: x[2] += 2000 s = "{0:>02n}/{1:>02n}/{2:4n}".format(*x) #print("convertDate2String: ", x, " ", s) return s # draw it centered y mm from top def draw_heading(self, y): # canvas.saveState() self.canvas.setFont('DejaVu', 20) (cx, cy) = self.coord(self.pageWidth / 2.0, y) self.canvas.drawCentredString(cx, cy, self.title) # canvas.restoreState() # draw the tutor's details; here x, y is the bottom left # corner of the first line in mm def draw_tutor(self, x, y): # canvas.saveState() cx, cy = self.coord(x, y) self.canvas.setFont('DejaVu-Bold', 13) self.canvas.drawString(cx, cy, self.tutorData[0]) self.canvas.setFont('DejaVu', 10) cy -= 15 self.canvas.drawString(cx, cy, "address:") self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[1]) cy -= 13 self.canvas.drawString(cx, cy, "phone:") self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[2]) cy -= 13 self.canvas.drawString(cx, cy, "email:") self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[3]) # canvas.restoreState() # draw the date; again x, y are in mm # y is the distance from the top # x is the distance from the right def draw_invoice_date(self, x, y): # canvas.saveState() cx, cy = self.coord(x, y, fromRight=True) self.canvas.setFont('DejaVu-Bold', 10) self.canvas.drawRightString(cx, cy, "invoice date:") self.canvas.setFont('DejaVu', 10) cy -= 12 # go 12 pixels lower self.canvas.drawRightString(cx, cy, self.invoiceHeader[0]) # canvas.restoreState() # draw the date; y is in mm # y is the distance from the top def draw_invoice_data(self, y): middlex = 80 # canvas.saveState() cx, cy = self.coord(self.lMargin, y) self.canvas.setFont('DejaVu-Bold', 11) self.canvas.drawString(cx, cy, "invoice to:") cx, cy = self.coord(middlex, y) self.canvas.drawString(cx, cy, "invoice for:") cx, cy = self.coord(self.pageWidth - 20, y) self.canvas.drawRightString(cx, cy, "invoice reference nr:") self.canvas.setFont('DejaVu', 10) cy -= 12 # go 12 pixels lower cx = self.lMargin * mm self.canvas.drawString(cx, cy, self.invoiceHeader[1]) cx = middlex * mm self.canvas.drawString(cx, cy, self.invoiceHeader[2]) cx = (self.pageWidth - 20) * mm self.canvas.drawRightString(cx, cy, self.invoiceHeader[3]) # canvas.restoreState() # draw table # y is the distance in mm from top def draw_table(self, y): vspace = 4 y += 8 self.headStyle = TableStyle([('FONT', (0, 0), (-1, 0), 'DejaVu-Bold', 10), ('GRID', (0, 0), (-1, 0), 2, black)]) self.bodyStyle = TableStyle([('FONT', (0, 0), (-1, -1), 'DejaVu', 10), ('BOX', (0, 0), (-1, -1), 2, black), ('LINEBEFORE', (1, 0), (1, -1), 2, black), ('LINEBEFORE', (2, 0), (2, -1), 2, black), ('LINEBEFORE', (3, 0), (3, -1), 2, black), ('LINEBEFORE', (4, 0), (4, -1), 2, black), ('LINEBEFORE', (5, 0), (5, -1), 2, black), ('ALIGN', (3, 0), (5, -1), 'RIGHT')]) self.footStyle = TableStyle([ ('FONT', (0, 0), (-1, 0), 'DejaVu-Bold', 10), ('BOX', (0, 0), (-1, -1), 2, black), ('ALIGN', (0, 0), (0, 0), 'CENTER'), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ('LINEBEFORE', (1, 0), (1, -1), 2, black) ]) dataBody = [] num = 0 for lesson in self.invoiceData: #print("Line: ", lesson) num += 1 line = lesson[0:2] line.append("teaching") line.append("{0:3.2f}".format(lesson[2])) line.append(self.cM2S(lesson[3])) line.append(self.cM2S(lesson[4])) dataBody.append(line) lRest = lesson[5:] while lRest: num += 1 extra_reason = lRest.pop(0) extra_cost = self.cM2S(lRest.pop(0)) line2 = [None, None, extra_reason, None, None, extra_cost] dataBody.append(line2) self.bodyStyle.add('LINEABOVE', (0, num), (-1, num), 2, black) dataHead = [[ "date", "tuition reference", "description", "hours", "rate", "amount" ]] dataFoot = [["total", self.cM2S(self.invoiceHeader[-1])]] colWiMMB = [25, 48, 42, 16, 18, 20] colWiMMF = [sum(colWiMMB[0:-1]), colWiMMB[-1]] colWidthB = self.trans(colWiMMB) colWidthF = self.trans(colWiMMF) #print(colWiMMB, colWiMMF) self.tableHead = Table(dataHead, colWidths=colWidthB, style=self.headStyle) self.tableBody = Table(dataBody, colWidths=colWidthB, style=self.bodyStyle, repeatRows=0) self.tableFoot = Table(dataFoot, colWidths=colWidthF, style=self.footStyle) sw, sh = self.tableHead.wrapOn(self.canvas, *self.trans([180, 10])) tw, th = self.tableBody.wrapOn(self.canvas, *self.trans([180, 120])) uw, uh = self.tableFoot.wrapOn(self.canvas, *self.trans([180, 10])) xx, yy = self.coord(self.lMargin, y) ay = yy - sh by = ay - th - vspace cy = by - uh - vspace theight = (sh + th + uh + 2 * vspace) / mm self.tableHead.drawOn(self.canvas, xx, ay) self.tableBody.drawOn(self.canvas, xx, by) self.tableFoot.drawOn(self.canvas, xx, cy) return theight # draw the date; y is in mm # y is the distance from the top def draw_invoice_foot(self, y): # canvas.saveState() cx, cy = self.coord(self.pageWidth / 2.0, y + 6) self.canvas.setFont('DejaVu', 10) # theight is becoming the total height of # the footer theight = 10 self.canvas.drawCentredString( cx, cy, "Please pay by bank transfer to following account within 7 calendar days of invoice date:" ) cy -= 13 theight += 13 self.canvas.drawCentredString( cx, cy, "Account Title: Hannes Buchholzer, Sort Code: 20-42-58, Account Number: 23821595." ) cy -= 13 theight += 13 self.canvas.setFont('DejaVu-Italics', 10) self.canvas.drawCentredString( cx, cy, "Please set the reference as the invoice reference number :") cy -= 20 theight += 20 self.canvas.setFont('DejaVu', 12) cx = self.trans(self.pageWidth / 2.0) self.canvas.drawCentredString(cx, cy, self.invoiceHeader[3]) cy -= 20 theight += 20 self.canvas.setFont('DejaVu', 10) self.canvas.drawCentredString( cx, cy, "Thank you for choosing me as your Tutor!") theight = theight / mm # convert into mm return theight def compileInvoice(self): self.draw_heading(30) self.draw_tutor(20, 50) self.draw_invoice_date(20, 50) self.draw_invoice_data(90) height1 = self.draw_table(110) yfoot = 120 + height1 + 20 if yfoot <= 250.0: height2 = self.draw_invoice_foot(yfoot) else: self.canvas.showPage() height2 = self.draw_invoice_foot(35) self.canvas.save()
class pdf: def __init__(self, path: str, name: str = 'generated'): """ Create a pdf-file object\n :param path: path to create file :param name: name of file """ self.file = Canvas(self._get_path(path, name)) self.set_font(12) self.page = 1 def _get_path(self, path: str, name: str = 'generated') -> str: """ This function cleans path\n :param path: path to create file :param name: name of file :return: clean path to file """ path = ''.join(symbol for symbol in path.lower() if symbol not in ' <>?"\*') while path.count(':') > 1: path = path[:path.rfind(':')] + path[path.rfind(':') + 1:] while path[len(path) - 1] == ' ': path = path[:len(path) - 1] if ".pdf" in path: path = path[0:path.rfind('/') + 1:1] if path[len(path) - 1] != '/': path += '/' if '.pdf' in name: name = name[:name.rfind('.')] return path + name + '.pdf' def _format_data(self, data: dict) -> list: """ This function processing data and return list of data for create table\n :param data: dict of data :return: list of data """ new_data = [[data['title']]] add_list = [] value_list = [] for column_elem in data['columns']: add_list.append(column_elem['name']) value_list.append(column_elem['value']) new_data.append(add_list.copy()) add_list.clear() for row_elem in data['rows']: for value in value_list: add_list.append(row_elem[value]) new_data.append(add_list.copy()) add_list.clear() return new_data def _normal_color(self): self.file.setFillColor('black') self.file.setStrokeColor('black') def set_font(self, font_size: int): """ This function set up font and his size in file\n :param font_size: size of font """ self.font_size = font_size using_font = ttfonts.TTFont("Calibri", "Calibri.ttf") pdfmetrics.registerFont(using_font) self.file.setFont("Calibri", self.font_size) def write_text(self, text: str, position: str = "mid", x: int = 297, y: int = 815): """" This function write text on defined position\n size of page is 595,841\n :param text: string of text to writing :param position: left/mid/right position of string of text :param x, y: coordinates of string """ self._normal_color() if position == "left": self.file.drawString(x, y, text) elif position == "mid": self.file.drawCentredString(x, y, text) elif position == "right": self.file.drawRightString(x, y, text) def random_drawing(self, fg_count: int): """ This function draws random picture\n :param fg_count: count of figures, drawn on page """ for figure in range(fg_count): methods = [ self.file.bezier(randint(150, 495), randint(150, 741), randint(150, 495), randint(150, 741), randint(150, 495), randint(150, 741), randint(150, 495), randint(150, 741)), self.file.arc(randint(100, 495), randint(100, 741), randint(100, 495), randint(100, 741)), self.file.rect(randint(100, 395), randint(100, 641), randint(1, 100), randint(1, 100), fill=randint(0, 1)), self.file.ellipse(randint(100, 495), randint(100, 741), randint(100, 495), randint(100, 741), fill=randint(0, 1)), self.file.circle(randint(100, 395), randint(100, 641), randint(1, 100), fill=randint(0, 1)), self.file.roundRect(randint(100, 395), randint(100, 641), randint(1, 100), randint(1, 100), randint(1, 100), fill=randint(0, 1)) ] self.file.setFillColorRGB(uniform(0, 1), uniform(0, 1), uniform(0, 1), alpha=uniform(0, 1)) self.file.setStrokeColorRGB(uniform(0, 1), uniform(0, 1), uniform(0, 1), alpha=uniform(0, 1)) choice(methods) def draw_table(self, data: dict, x: int = 10, y: int = 10): """ This function draws table from your dictionary of data\n size of page is 595.27,841.89\n :param data: dictionary with data, e.g. :param x, y: coordinates of left-bottom corner of table { 'title': 'Table title', 'columns': [ {'name': 'Name', 'value': 'name'}, {'name': 'Age', 'value': 'age'} ], 'rows': [ {'name': 'string1', 'age': 23}, {'name': 'string2', 'age': 43} ] } """ self._normal_color() data = self._format_data(data) table = Table(data=data, style=[("GRID", (0, 1), (-1, -1), 1, "Black"), ("FONT", (0, 0), (-1, -1), "Calibri", self.font_size), ("BOX", (0, 0), (-1, -1), 1, "Black")]) table.wrapOn(self.file, 10, 10) table.drawOn(self.file, x, y) def insert_image(self, path: str, x: int = 100, y: int = 200, width: int = None, height: int = None): """ This function inserts image in pdf-file\n size of page is 595.27,841.89\n :param path: path to image :param x, y: coordinates of left-bottom corner of image :param width, height: sizes of image """ image = Image(path, width, height) image.drawOn(self.file, x, y) def next_page(self): """ This function turns the page\n """ self._normal_color() self.file.drawString(565, 30, str(self.page)) self.page += 1 self.file.showPage() def save(self, author: str = 'pdf_gen', title: str = 'GENERATED'): """ This function saves our file\n :param author: author of file :param title: title of file """ self._normal_color() self.file.drawString(565, 30, str(self.page)) self.file.setAuthor(author) self.file.setTitle(title) self.file.save()
def _on_first_page(self, canvas: Canvas, doc): canvas.setCreator('NETWAYS') canvas.setTitle( pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) canvas.saveState() canvas.setFont('OpenSans', 8) canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page, )) for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip()) # https://docs.pretix.eu/en/latest/api/resources/invoices.html # https://docs.pretix.eu/en/latest/api/resources/orders.html try: vatId = self.invoice.order.invoice_address.vat_id # NET specific for country vat IDs if vatId and vatId.startswith("NL"): vatIdFooterNL = "Reverse Charge: BTW Verlegd naar %s According to Art. 12. 3 WOB" % ( vatId) i += 1 canvas.drawCentredString(self.pagesize[0] / 2, 40 + (3.5 * i) * mm, vatIdFooterNL) # DEBUG #i += 1 #canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, "DEBUG: %s" % (vatId)); except AttributeError: pass # Left, Invoice From textobject = canvas.beginText(25 * mm, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice from').upper()) canvas.drawText(textobject) p = Paragraph(self.invoice.full_invoice_from.strip().replace( '\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 70 * mm, 50 * mm) p_size = p.wrap(70 * mm, 50 * mm) p.drawOn(canvas, 25 * mm, (297 - 17) * mm - p_size[1]) # Left, Invoice To textobject = canvas.beginText(25 * mm, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice to').upper()) canvas.drawText(textobject) p = Paragraph(self.invoice.invoice_to.strip().replace( '\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 85 * mm, 50 * mm) p_size = p.wrap(85 * mm, 50 * mm) p.drawOn(canvas, 25 * mm, (297 - 52) * mm - p_size[1]) rightX = 95 * mm # Right, Order code textobject = canvas.beginText(rightX, (297 - 38) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Order code').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.order.full_code) canvas.drawText(textobject) # Right, * number textobject = canvas.beginText(rightX, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) if self.invoice.is_cancellation: textobject.textLine( pgettext('invoice', 'Cancellation number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Original invoice').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.refers.number) else: textobject.textLine(pgettext('invoice', 'Invoice number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) # Right, * date if self.invoice.is_cancellation: textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Cancellation date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Original invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine( date_format(self.invoice.refers.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) else: textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) canvas.drawText(textobject) # Right, Invoice and Event Logo rightLogoX = 160 * mm if self.invoice.event.settings.logo_image: logo_file = self.invoice.event.settings.get('logo_image', binary_file=True) canvas.drawImage(ImageReader(logo_file), rightLogoX, (297 - 38) * mm, width=25 * mm, height=25 * mm, preserveAspectRatio=True, anchor='n', mask='auto') if self.invoice.event.settings.invoice_logo_image: logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) canvas.drawImage(ImageReader(logo_file), rightLogoX, (297 - 63) * mm, width=25 * mm, height=25 * mm, preserveAspectRatio=True, anchor='n', mask='auto') # Right, Event if self.invoice.event.settings.show_date_to: p_str = ( str(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format( from_date=self.invoice.event.get_date_from_display(), to_date=self.invoice.event.get_date_to_display())) else: p_str = (str(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display()) p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 65 * mm, 50 * mm) p_size = p.wrap(65 * mm, 50 * mm) p.drawOn(canvas, 95 * mm, (297 - 17) * mm - p_size[1]) textobject = canvas.beginText(rightX, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Event').upper()) canvas.drawText(textobject) canvas.restoreState()
class BadgeGen(): rowcount = 5 colcount = 2 def __init__(self, festival, output): self.canvas = Canvas(output, pagesize=A4) self.canvas.setLineWidth(0.25) self.pagemargin = 20*mm self.rowheight = (A4[1] - self.pagemargin*2.0)/BadgeGen.rowcount self.colwidth = (A4[0] - self.pagemargin*2.0)/BadgeGen.colcount self.index = 0 self.bps = BadgeGen.rowcount * BadgeGen.colcount self.colour = None self.festival = festival self.logoimage = None if self.festival['logo']: self.logoimage = ImageReader(self.festival['logo']) (w, h) = self.logoimage.getSize() if w > h: # Wide image. self.logowidth = 20*mm self.logoheight = h*20*mm/w else: # Tall image. self.logoheight = 20*mm self.logowidth = w*20*mm/h else: self.logoheight = self.logowidth = 0 # Size the festival name to fit fontsize = 18 availableWidth = self.colwidth - self.logowidth - 4*mm while (self.canvas.stringWidth(self.festival["name"], "Times-Roman", fontsize) > availableWidth): fontsize -= 1 self.festname_fontsize = fontsize if self.logoimage: if self.canvas.stringWidth(self.festival["name"], "Times-Roman", fontsize) < (availableWidth - self.logowidth): # Centre text on whole badge self.festname_x = self.colwidth/2 else: # Centre text between logo and RHS self.festname_x = self.colwidth/2 + self.logowidth/2 self.festname_y = self.rowheight - self.logoheight/2 - fontsize/2 else: self.festname_x = self.colwidth/2 self.festname_y = self.rowheight - 3*mm - fontsize/2 def _setup_page(self): # Draw cutting lines around edge of page. self.canvas.setLineWidth(0.25) for col in range(0, self.colcount + 1): x = self.pagemargin + col * self.colwidth self.canvas.line (x, 0, x, self.pagemargin * 0.9) self.canvas.line (x, A4[1], x, A4[1] - self.pagemargin * 0.9) for row in range(0, self.rowcount + 1): y = self.pagemargin + row * self.rowheight self.canvas.line (0, y, self.pagemargin * 0.9, y) self.canvas.line (A4[0], y, A4[0] - self.pagemargin * 0.9, y) # Output the colour if needed. if self.colour and ((self.index % self.bps) == 0): self.canvas.setFont("Times-Bold", 14) self.canvas.drawCentredString(A4[0]/2, A4[1] - self.pagemargin/2 - 7, "To be printed on %s paper" % self.colour) def Render(self, data, colour=None): if data['altname']: # Double sided badge - check we're in the right place. while self.index % self.colcount != 0: self.index += 1 if self.index == 0: self._setup_page() elif (self.colour != colour) or (self.index % self.bps == 0): # Start a fresh page - either we finished the last one or these need a different colour. self.canvas.showPage() self.colour = colour self._setup_page() # Local copy of index within the page. index = self.index % self.bps # Work out the co-ordinates for this index left = (index % BadgeGen.colcount) * self.colwidth + self.pagemargin bottom = (BadgeGen.rowcount - 1 - ((index // BadgeGen.colcount) % BadgeGen.rowcount)) * self.rowheight + self.pagemargin width = self.colwidth height = self.rowheight # Draw a box around the whole badge #self.canvas.setLineWidth(0.25) #self.canvas.rect (left, bottom, width, height) # Draw the logo, 2mm in from the top left, in a box if self.logoimage: logobottom = bottom + height - self.logoheight - 2*mm self.canvas.drawImage(self.logoimage, left + 2*mm, logobottom, self.logowidth, self.logoheight, preserveAspectRatio=True, anchor='nw') # Add the festival name, to the right of the logo self.canvas.setFont("Times-Roman", self.festname_fontsize) self.canvas.drawCentredString(self.festname_x + left, self.festname_y + bottom, self.festival['name']) # Add the volunteer name, just below the middle of the badge. fontsize = 22 volname = data['name'] while (self.canvas.stringWidth(volname, "Times-Bold", fontsize) > (width - 4*mm)): fontsize -= 1 self.canvas.setFont("Times-Bold", fontsize) self.canvas.drawCentredString(left + width/2, (bottom + height/2)-(fontsize/2)-2*mm, volname) # Add the job title, centred, 3mm in from the bottom. if data['job']: fontsize = 16 jobname = data['job'] while (self.canvas.stringWidth(jobname, "Times-Roman", fontsize) > (width - 40*mm)): fontsize -= 1 self.canvas.setFont("Times-Roman", fontsize) self.canvas.drawCentredString(left + width/2, bottom+3*mm, jobname) if data['id']: self.canvas.setFont("Courier", 8) self.canvas.drawRightString(left + width - 1*mm, bottom+3*mm, data['id']) # Barcode code = code128.Code128(data['id']) code.drawOn(self.canvas, left - 3*mm, bottom+2*mm) self.index = index + 1 if data['altname']: # Call ourselves to render the alternative badge on the other half. data['name'] = data['altname'] data['altname'] = None self.Render (data, colour) def Save(self): # Fill the rest of the sheet with useful blanks. blank = {'name':'', 'job':'Volunteer', 'altname':None, 'id':None} while self.index % self.bps: self.Render (blank, self.colour) self.canvas.save()
can.setFillColorCMYK(.7,0,.5,0) # couleur de remplissage (CMJN) can.ellipse(3*cm, 4*cm, 19*cm, 10*cm, fill=1) # ellipse (! axes = 16 x 6 cm) can.setLineWidth(1) # nouvelle épaisseur des lignes can.ellipse(centreX -.5*cm, centreY -.5*cm, # petit cercle indiquant la centreX +.5*cm, centreY +.5*cm) # position du centre de la page # Quelques textes, avec polices, orientation et alignement divers : can.setFillColor("navy") # couleur des textes texteC ="Petite pluie abat grand vent." # texte à centrer can.setFont("Times-Bold", 18) can.drawCentredString(centreX, centreY, texteC) texteG ="Qui ne risque rien, n'a rien." # texte à aligner à gauche can.setFont("Helvetica", 18) can.drawString(centreX, centreY -1*cm, texteG) texteD ="La nuit porte conseil." # texte à aligner à droite can.setFont("Courier", 18) can.drawRightString(centreX, centreY -2*cm, texteD) texteV ="L'espoir fait vivre." # texte à disposer verticalement can.rotate(90) can.setFont("Times-Italic", 18) can.drawString(centreY +1*cm, -centreX, texteV) # ! inversion des coordonnées ! texteE ="L'exception confirme la règle" # texte à afficher en blanc can.rotate(-90) # retour à l'orientation horiz. can.setFont("Times-BoldItalic", 28) can.setFillColor("white") # nouvelle couleur des textes can.drawCentredString(centreX, 7*cm, texteE) can.save() # Sauvegarde du résultat
def _on_first_page(self, canvas: Canvas, doc): canvas.setCreator('pretix.eu') canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) canvas.saveState() canvas.setFont('OpenSans', 8) canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page,)) for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip()) textobject = canvas.beginText(25 * mm, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice from').upper()) canvas.drawText(textobject) self._draw_invoice_from(canvas) textobject = canvas.beginText(25 * mm, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice to').upper()) canvas.drawText(textobject) self._draw_invoice_to(canvas) textobject = canvas.beginText(125 * mm, (297 - 38) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Order code').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.order.full_code) canvas.drawText(textobject) textobject = canvas.beginText(125 * mm, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) if self.invoice.is_cancellation: textobject.textLine(pgettext('invoice', 'Cancellation number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Original invoice').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.refers.number) else: textobject.textLine(pgettext('invoice', 'Invoice number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) if self.invoice.is_cancellation: textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Cancellation date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Original invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.refers.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) else: textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) canvas.drawText(textobject) if self.invoice.event.settings.invoice_logo_image: logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) ir = ThumbnailingImageReader(logo_file) try: ir.resize(25 * mm, 25 * mm, 300) except: logger.exception("Can not resize image") pass canvas.drawImage(ir, 95 * mm, (297 - 38) * mm, width=25 * mm, height=25 * mm, preserveAspectRatio=True, anchor='n', mask='auto') def shorten(txt): txt = str(txt) p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p_size = p.wrap(65 * mm, 50 * mm) while p_size[1] > 2 * self.stylesheet['Normal'].leading: txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…' p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p_size = p.wrap(65 * mm, 50 * mm) return txt if not self.invoice.event.has_subevents: if self.invoice.event.settings.show_date_to and self.invoice.event.date_to: p_str = ( shorten(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format( from_date=self.invoice.event.get_date_from_display(), to_date=self.invoice.event.get_date_to_display()) ) else: p_str = ( shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display() ) else: p_str = shorten(self.invoice.event.name) p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 65 * mm, 50 * mm) p_size = p.wrap(65 * mm, 50 * mm) p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1]) textobject = canvas.beginText(125 * mm, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Event').upper()) canvas.drawText(textobject) canvas.restoreState()
def _on_first_page(self, canvas: Canvas, doc): canvas.setCreator('pretix.eu') canvas.setTitle( pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) canvas.saveState() canvas.setFont('OpenSans', 8) canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page, )) for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip()) textobject = canvas.beginText(25 * mm, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice from').upper()) canvas.drawText(textobject) p = Paragraph(self.invoice.invoice_from.strip().replace( '\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 70 * mm, 50 * mm) p_size = p.wrap(70 * mm, 50 * mm) p.drawOn(canvas, 25 * mm, (297 - 17) * mm - p_size[1]) textobject = canvas.beginText(25 * mm, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice to').upper()) canvas.drawText(textobject) p = Paragraph(self.invoice.invoice_to.strip().replace( '\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 85 * mm, 50 * mm) p_size = p.wrap(85 * mm, 50 * mm) p.drawOn(canvas, 25 * mm, (297 - 52) * mm - p_size[1]) textobject = canvas.beginText(125 * mm, (297 - 38) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Order code').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.order.full_code) canvas.drawText(textobject) textobject = canvas.beginText(125 * mm, (297 - 50) * mm) textobject.setFont('OpenSansBd', 8) if self.invoice.is_cancellation: textobject.textLine( pgettext('invoice', 'Cancellation number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Original invoice').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.refers.number) else: textobject.textLine(pgettext('invoice', 'Invoice number').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) if self.invoice.is_cancellation: textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Cancellation date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) textobject.setFont('OpenSansBd', 8) textobject.textLine( pgettext('invoice', 'Original invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine( date_format(self.invoice.refers.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) else: textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont('OpenSans', 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) canvas.drawText(textobject) if self.invoice.event.settings.invoice_logo_image: logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) canvas.drawImage(ImageReader(logo_file), 95 * mm, (297 - 38) * mm, width=25 * mm, height=25 * mm, preserveAspectRatio=True, anchor='n', mask='auto') if self.invoice.event.settings.show_date_to: p_str = ( str(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format( from_date=self.invoice.event.get_date_from_display(), to_date=self.invoice.event.get_date_to_display())) else: p_str = (str(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display()) p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 65 * mm, 50 * mm) p_size = p.wrap(65 * mm, 50 * mm) p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1]) textobject = canvas.beginText(125 * mm, (297 - 15) * mm) textobject.setFont('OpenSansBd', 8) textobject.textLine(pgettext('invoice', 'Event').upper()) canvas.drawText(textobject) canvas.restoreState()
def impr_recibo(request, pk): mitad = 14.8 * cm mita = 14.8 # Inicializo todos los comprobantes y valores recibo = Recibo.objects.get(pk=pk) a_cuenta = recibo.a_cuenta # Datos de comprobantes comprobantes = recibo.detalle_cobro_set.all() # a_cuenta = recibo.cobranza_a_cuenta_set.all() # credito_anterior = recibo.cobranza_credito_anterior_set.all() # Datos de valores valores = recibo.dinero_set.all() # transferencia = recibo.transferenciabancariaentrante_set.all() # efectivo = recibo.dinero_set.all() response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'filename="somefilename.pdf"' p = Canvas(response, pagesize=A4) # Numero de recibo p.setFont('Helvetica-Bold', 16) p.drawString(15.7 * cm, 13 * cm, recibo.numero_full) # Fecha p.setFont('Helvetica', 13) p.drawString(17 * cm, 12 * cm, str(recibo.fecha.day)) p.drawString(18 * cm, 12 * cm, str(recibo.fecha.month)) p.drawString(19 * cm, 12 * cm, str(recibo.fecha.year)) # Datos del cliente p.setFont('Helvetica', 13) p.drawString(12 * cm, 11 * cm, recibo.cliente.razon_social) p.drawString(12 * cm, 10.3 * cm, recibo.cliente.get_cond_iva_display()) p.drawString(12 * cm, 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit) p.drawString(12 * cm, 9.3 * cm, recibo.cliente.direccion) p.drawString(12 * cm, 8.8 * cm, "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display())) inicio_y = 6.2 alto_item = 0.4 i = 0 p.setFont('Helvetica', 7) if a_cuenta and a_cuenta > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta) i += 1 if recibo.credito_anterior and recibo.credito_anterior > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior) i += 1 for item in comprobantes: p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo) p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full()) p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa()) p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d()) i += 1 # Cheques i = 0 for item in valores: try: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero) p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular) p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa()) p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20]) p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: try: item.transferenciabancariaentrante p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) finally: i += 1 # for item in transferencia: # p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Transferencia Bancaria") # p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto) # i+=1 # for item in efectivo: # p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Efectivo") # p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto) # i+=1 p.setFont('Helvetica-Bold', 12) p.drawString(7.5 * cm, 2.3 * cm, recibo.total_str) p.drawString(18 * cm, 2.3 * cm, recibo.total_str) try: letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word( int(recibo.total_str.split('.')[1].strip())) + "centavos").lower() except IndexError: letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower() p.setFont('Helvetica', 9) p.drawString(2 * cm, 7.5 * cm, letra) ###################################################### ##############RECIBO DUPLICADO######################## ###################################################### # Numero de recibo p.setFont('Helvetica-Bold', 16) p.drawString(15.7 * cm, mitad + 13 * cm, recibo.numero_full) # Fecha p.setFont('Helvetica', 13) p.drawString(17 * cm, mitad + 12 * cm, str(recibo.fecha.day)) p.drawString(18 * cm, mitad + 12 * cm, str(recibo.fecha.month)) p.drawString(19 * cm, mitad + 12 * cm, str(recibo.fecha.year)) # Datos del cliente p.setFont('Helvetica', 13) p.drawString(12 * cm, mitad + 11 * cm, recibo.cliente.razon_social) p.drawString(12 * cm, mitad + 10.3 * cm, recibo.cliente.get_cond_iva_display()) p.drawString(12 * cm, mitad + 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit) p.drawString(12 * cm, mitad + 9.3 * cm, recibo.cliente.direccion) p.drawString(12 * cm, mitad + 8.8 * cm, "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display())) # Datos de comprobantes # comprobantes = recibo.detalle_cobro_set.all() inicio_y = mita + 6.2 alto_item = 0.4 i = 0 p.setFont('Helvetica', 7) if a_cuenta and a_cuenta > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta) i += 1 if recibo.credito_anterior and recibo.credito_anterior > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior) i += 1 for item in comprobantes: p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo) p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full()) p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa()) p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d()) i += 1 i = 0 for item in valores: try: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero) p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular) p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa()) p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20]) p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: try: item.transferenciabancariaentrante p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) finally: i += 1 p.setFont('Helvetica-Bold', 12) p.drawString(7.5 * cm, mitad + 2.3 * cm, recibo.total_str) p.drawString(18 * cm, mitad + 2.3 * cm, recibo.total_str) try: letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word( int(recibo.total_str.split('.')[1].strip())) + "centavos").lower() except IndexError: letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower() p.setFont('Helvetica', 9) p.drawString(2 * cm, mitad + 7.5 * cm, letra) p.showPage() p.save() return response
class DancerPDF(): def __init__(self): self.reporter = Reporter() ################################################################## # *Abs. means a coordinate position according to reportlab. These are # full-page, centred bottom left. # *Raw means a coordinate position on stock. This includes # margins (so the stock). # *Raw is centred top left stock, even though reportlab works from # bottom left. # *Raw can be converted to reportlab coordinates using the functions # rawToAbsX() and rawToAbsY() # ## Page size ## self.pageStock = A4 ## reportlab canvas ## #! as instance? self.c = Canvas("test.pdf", pagesize=self.pageStock) ## Stock ## #! no, 'typeblock' self._pageHeight = self.pageStock[1] self._pageWidth = self.pageStock[0] self._centerPage = self._pageWidth / 2 self.leftMargin = mm * 20 self.rightMargin = mm * 20 self.topMargin = mm * 20 self.bottomMargin = mm * 40 self.rightStockAbs = self._pageWidth - self.rightMargin self.leftStockAbs = self.leftMargin self.topStockAbs = self._pageHeight - self.topMargin self.bottomStockAbs = self.bottomMargin # passed to renderMoveBlock self.stockContext = [ self._pageHeight, self._pageWidth, self.topStockAbs, self.rightStockAbs, self.leftStockAbs, self.bottomStockAbs, self.topMargin ] ########################################################### ## Page ## ## Title ## # carries space if necessary (when sections start) self.titleFontFamily = "Times-Roman" self.titleFontSize = 24 self.titleTopSkip = 8 # Internal # tracks the start height of the moves block # allowing space for main or section titles self._titleHeightRaw = 0 # currently 114, should be 95 ## Sections ## self.sectionFontFamily = "Times-Roman" self.sectionFontSize = 24 self.sectionTopSkip = 8 ## Credits ## # If used, credits are aligned under the title. However, they do not # contribute to the overall space above the # musicalDirections. This is to give maximum flexibility in overriding # (for example, they could be in a column to the right of musical # directions). To make space for them, increase musicalDirectionsTopSkip. self.creditsFontFamily = "Times-Roman" self.creditsFontSize = 14 # above first credit self.creditsTopSkip = 0 # above each credit self.creditLineTopSkip = 4 ## Move block essentials ## # Declared early because musical directions need to be aligned with the # opening time signature. # fixed space to go before music. # This is inserted at the beginning of lines which # contain only music. # This needs to be something, or the first move will sit on the # first barline. About a quarter of the overall glue/note spacing # is ok. self.moveLineMusicOnlyLeftSkip = 14 # Many music scores adopt an indent. Not often applicable here, so will # usually be zero. If you have any material starting a move line, use it. # This variable can not be calculated (font width of time signature, # and other material). # NOT IMPLEMENTED #moveblockFirstLineIndent = 0 # Amount of glue for a barline (apears after the barline), by our # current calculation. Works best round 0.5. self.barlineGlue = 0.5 # The last line in any block may not have the right number of bars. # The simplistic solution here, if the line is within this number of # bars then it will stretched to full width, otherwise the line is # rendered as stopping short. To always stretch, make this a relativly # large number e.g. 12. 0 will never stretch. self.lastMovelineGlueMax = 2 ## MusicalDirections ## self.musicalDirectionFontFamily = "Times-Bold" self.musicalDirectionFontSize = 9 self.musicalDirectionBottomSkip = 12 self._musicalDirectionContext = [ self.musicalDirectionFontFamily, self.musicalDirectionFontSize, self.musicalDirectionBottomSkip ] #################################################################### ## The move block ## # The move block is almost all automatic layout. This has it's # diadvantages, but we will see.... # Space above the block. # Used to add space for the top line of tempo marks, clearing the # freely placed credits. self.movesBlockTopSkip = 24 # gap between lines. Don't make too small. self.movesLineTopSkip = 96 #################################################################### ## Time signature ## self.timeMarkFontFamily = "Times-Roman" self.timeMarkFontSize = 16 # Reserve space for time signatures. # For marks at line starts and inline. # This variable can not be calculated (possible width of oversize font). # If the time signature font size is changed, alter by hand. # Should be, say, 3/2 of the width of the fonts as written as glyphs. self.timeMarkWidth = 24 # How far down from the line to drop a time signature self.timeMarkSkipDown = 24 # Fixed allocation for indenting a time mark. # The time mark sits at the beginning of it's allocation. this is # used to push from barlines (and other preceeding content?). # Should only be a handful of points. #! while this is necessary and good, more is needed. A pre-music # indent to go after time signatures and before lines without time # marks would be helpful. self.timeMarkLeftSkip = 4 #timeMarkLeftSkip = 0 self._timeMarkContext = [ self.timeMarkFontFamily, self.timeMarkFontSize, self.timeMarkWidth, self.timeMarkSkipDown, self.timeMarkLeftSkip ] ## moveLines ## # Express an interest in how many bars to a line # In many circumstances, will not be honoured. But used for open # bar rendering, so will stretch bars to fit the page width. #! what about sheet width, etc.? self.barPerLineAim = 5 # fixed width for barmarks to occupy self.barmarkWidth = 24 # The minimum glue allowed before bars are spilled to the next line self.minMoveGlueWidth = 14 self.moveLineContentFontFamily = "Times-Roman" self.moveLineContentFontSize = 12 # space down from the moveline to the move marks self.moveLineContentSkipDown = 8 self.moveLineContentContext = [ self.moveLineContentFontFamily, self.moveLineContentFontSize, self.moveLineContentSkipDown, self.moveLineMusicOnlyLeftSkip ] def addInstruction(self, m): self.mbr.addInstruction(m) def save(self): self.c.save() ################################################################# ########################################################### ## Coordinate functions ## # rawToAbsX() and rawToAbsY() convert *Raw positions to *Abs # #? unused def rawToAbsX(self, x): return self.leftMargin + x def rawToAbsY(self, y): return self.topStockAbs - y def title(self, title): self.c.setFont(self.titleFontFamily, self.titleFontSize) self.c.drawCentredString(self._centerPage, self.rawToAbsY(self.titleTopSkip), title) self._titleHeightRaw = self.titleTopSkip + self.titleFontSize #! TODO def section(self, title): # initialize self.c.showPage() self._titleHeightRaw = 0 # render self.c.setFont(self.sectionFontFamily, self.sectionFontSize) self.c.drawCentredString(self._centerPage, self.rawToAbsY(self.sectionTopSkip), title) self._titleHeightRaw = self.sectionTopSkip + self.sectionFontSize def titleCredits(self, performers, transcribedBy): self.c.setFont(self.creditsFontFamily, self.creditsFontSize) #48 self.c.drawRightString( self.rightStockAbs, self.rawToAbsY(self._titleHeightRaw + self.creditsTopSkip), performers) self._titleHeightRaw += self.creditsTopSkip + self.creditsFontSize #68 self.c.drawRightString( self.rightStockAbs, self.rawToAbsY(self._titleHeightRaw + self.creditLineTopSkip), "Trns: " + transcribedBy) # Opens a movesblock def movesblock(self): self._titleHeightRaw += self.movesBlockTopSkip return MoveBlockRender( self.c, self.reporter, stockContext=self.stockContext, barsInLineAim=self.barPerLineAim, lineTopSkip=self.movesLineTopSkip, firstPageTopSkip=self._titleHeightRaw, #moveblockFirstLineIndent = moveblockFirstLineIndent, barlineGlue=self.barlineGlue, minMoveGlueWidth=self.minMoveGlueWidth, lastMovelineGlueMax=self.lastMovelineGlueMax, musicalDirectionContext=self._musicalDirectionContext, timeMarkContext=self._timeMarkContext, moveLineContentContext=self.moveLineContentContext) ## Utils ## #x deprecated, when we get times and tempo in the block class def moveLineYRaw(self, idx): # positioning for each line return self._titleHeightRaw + (self.movesLineTopSkip * idx)
def impr_recibo(request, pk): mitad = 14.8 * cm mita = 14.8 # Inicializo todos los comprobantes y valores recibo = Recibo.objects.get(pk=pk) a_cuenta = recibo.a_cuenta # Datos de comprobantes comprobantes = recibo.detalle_cobro_set.all() # a_cuenta = recibo.cobranza_a_cuenta_set.all() # credito_anterior = recibo.cobranza_credito_anterior_set.all() # Datos de valores valores = recibo.dinero_set.all() # transferencia = recibo.transferenciabancariaentrante_set.all() # efectivo = recibo.dinero_set.all() response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'filename="somefilename.pdf"' p = Canvas(response, pagesize=A4) # Numero de recibo p.setFont('Helvetica-Bold', 16) p.drawString(15.7 * cm, 13 * cm, recibo.numero_full) # Fecha p.setFont('Helvetica', 13) p.drawString(17 * cm, 12 * cm, str(recibo.fecha.day)) p.drawString(18 * cm, 12 * cm, str(recibo.fecha.month)) p.drawString(19 * cm, 12 * cm, str(recibo.fecha.year)) # Datos del cliente p.setFont('Helvetica', 13) p.drawString(12 * cm, 11 * cm, recibo.cliente.razon_social) p.drawString(12 * cm, 10.3 * cm, recibo.cliente.get_cond_iva_display()) p.drawString(12 * cm, 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit) p.drawString(12 * cm, 9.3 * cm, recibo.cliente.direccion) p.drawString( 12 * cm, 8.8 * cm, "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display())) inicio_y = 6.2 alto_item = 0.4 i = 0 p.setFont('Helvetica', 7) if a_cuenta and a_cuenta > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta) i += 1 if recibo.credito_anterior and recibo.credito_anterior > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior) i += 1 for item in comprobantes: p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo) p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full()) p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa()) p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d()) i += 1 # Cheques i = 0 for item in valores: try: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero) p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular) p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa()) p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20]) p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: try: item.transferenciabancariaentrante p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: p.drawString( 10 * cm, (inicio_y - i * alto_item) * cm, "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) finally: i += 1 # for item in transferencia: # p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Transferencia Bancaria") # p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto) # i+=1 # for item in efectivo: # p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Efectivo") # p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto) # i+=1 p.setFont('Helvetica-Bold', 12) p.drawString(7.5 * cm, 2.3 * cm, recibo.total_str) p.drawString(18 * cm, 2.3 * cm, recibo.total_str) try: letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word(int(recibo.total_str.split('.')[1].strip())) + "centavos").lower() except IndexError: letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower() p.setFont('Helvetica', 9) p.drawString(2 * cm, 7.5 * cm, letra) ###################################################### ##############RECIBO DUPLICADO######################## ###################################################### # Numero de recibo p.setFont('Helvetica-Bold', 16) p.drawString(15.7 * cm, mitad + 13 * cm, recibo.numero_full) # Fecha p.setFont('Helvetica', 13) p.drawString(17 * cm, mitad + 12 * cm, str(recibo.fecha.day)) p.drawString(18 * cm, mitad + 12 * cm, str(recibo.fecha.month)) p.drawString(19 * cm, mitad + 12 * cm, str(recibo.fecha.year)) # Datos del cliente p.setFont('Helvetica', 13) p.drawString(12 * cm, mitad + 11 * cm, recibo.cliente.razon_social) p.drawString(12 * cm, mitad + 10.3 * cm, recibo.cliente.get_cond_iva_display()) p.drawString(12 * cm, mitad + 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit) p.drawString(12 * cm, mitad + 9.3 * cm, recibo.cliente.direccion) p.drawString( 12 * cm, mitad + 8.8 * cm, "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display())) # Datos de comprobantes # comprobantes = recibo.detalle_cobro_set.all() inicio_y = mita + 6.2 alto_item = 0.4 i = 0 p.setFont('Helvetica', 7) if a_cuenta and a_cuenta > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta) i += 1 if recibo.credito_anterior and recibo.credito_anterior > 0: p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior") p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior) i += 1 for item in comprobantes: p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo) p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full()) p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa()) p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d()) i += 1 i = 0 for item in valores: try: p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero) p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular) p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa()) p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20]) p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: try: item.transferenciabancariaentrante p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) except Dinero.DoesNotExist: p.drawString( 10 * cm, (inicio_y - i * alto_item) * cm, "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO") p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto) finally: i += 1 p.setFont('Helvetica-Bold', 12) p.drawString(7.5 * cm, mitad + 2.3 * cm, recibo.total_str) p.drawString(18 * cm, mitad + 2.3 * cm, recibo.total_str) try: letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word(int(recibo.total_str.split('.')[1].strip())) + "centavos").lower() except IndexError: letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower() p.setFont('Helvetica', 9) p.drawString(2 * cm, mitad + 7.5 * cm, letra) p.showPage() p.save() return response
class Report(object): render = {'table': render.TableRender, 'pie': render.PieRender, 'histo': render.HistoRender, 'line': render.LineRender, 'gantt': render.GanttRender, } margin = 30 big_title_height = 40 title_height = 50 frame_margin = 5 frag_title_height = 20 frag_margin = 9 edenwall_height = 60 def __init__(self, title, enterprise, interval, logo): self.title = title self.enterprise = enterprise self.interval = interval self.logo = logo self.width, self.height = A4 self.buf = StringIO() self.canvas = Canvas(self.buf, pagesize=A4) self.page_title = '' self.page_rows = [] self.page_frags = 0 self.page_num = 1 # Build story. self.canvas.saveState() self.canvas.setStrokeColor(colors.RED) self.canvas.setLineWidth(2) self.canvas.roundRect(self.margin, self.edenwall_height + self.margin, self.width, self.height, 20, stroke=1, fill=0) self.canvas.setFillColor(colors.GREEN2) self.canvas.setStrokeColor(colors.GREEN1) self.canvas.roundRect(- self.margin, - self.margin, self.width - self.margin, self.edenwall_height + self.margin, 20, stroke=1, fill=1) # TODO do not hardcode this values. img = Image('/var/lib/ufwi_rpcd/edenwall.png', 1209 / (300/(self.edenwall_height-self.margin/2)), self.edenwall_height-self.margin/2) img.drawOn(self.canvas, self.margin, self.margin/4) self.canvas.restoreState() if self.logo: img = Image(StringIO(self.logo)) img._setup_inner() img.drawOn(self.canvas, (self.width - self.margin)/2 - img.drawWidth/2, 2*self.height/3) offset = 40 self.canvas.setFillColor(black) self.canvas.setFont("Helvetica-Bold", self.big_title_height) self.canvas.drawCentredString((self.width-self.margin)/2, self.height/3, title) self.canvas.setFont("Helvetica-Bold", self.frag_title_height) self.canvas.drawString(offset, self.height - offset, enterprise) def __getstate__(self): d = self.__dict__.copy() del d['canvas'] return d def __setstate__(self, d): self.__dict__ = d self.canvas = Canvas(self.buf, pagesize=A4) def build(self): self.canvas.showPage() self.canvas.save() return self.buf def addGraph(self, title, columns, table, render): frags = self.page_frags for row, cols in enumerate(self.page_rows): frags -= cols if frags < 0: break if frags >= 0: self.addPage(self.page_title, self.page_rows) col = 0 row = 0 cols = self.page_rows[0] else: col = - frags - 1 # You can read that? Not me. x = self.margin + self.frame_margin + (col+1) * self.frag_margin + \ col * (self.width - 2*self.margin - 2*self.frame_margin - (col+1)*self.frag_margin) / cols y = self.margin + self.frame_margin + (row+1) * self.frag_margin + \ row * (self.height - 2*self.margin - 2*self.frame_margin - self.title_height - 2*self.frag_margin) / len(self.page_rows) width = (self.width - 2*self.margin - 2*self.frame_margin - 2*cols*self.frag_margin) / cols height = (self.height - 2*self.margin - 2*self.frame_margin - self.title_height - 2*len(self.page_rows)*self.frag_margin) / len(self.page_rows) self.canvas.setFillColor(colors.GREEN1) self.canvas.roundRect(x, y, width, height, 7, stroke=0, fill=1) self.canvas.setFillColor(white) x += 1 y += 1 width -= 2 height -= 2 self.canvas.roundRect(x, y, width, height - self.frag_title_height, 7, stroke=0, fill=1) self.canvas.setFillColor(white) self.canvas.setFont("Helvetica", 3*self.frag_title_height/4) self.canvas.drawCentredString(x + width/ 2, y + height - 3*self.frag_title_height/4, title) self.page_frags += 1 if len(table) > 0: klass = self.render[render] obj = klass(width, height - self.frag_title_height - 2*self.frame_margin, columns, table) r = obj.render() if isinstance(r, Drawing): renderPDF.draw(obj.render(), self.canvas, x, y + self.frame_margin) elif isinstance(r, Flowable): r.drawOn(self.canvas, x, y + height - self.frag_title_height - obj.height - self.frame_margin) else: pass #self.append(Paragraph(title, h2)) #self.append(Paragraph('No data', h2)) #self.append(KeepTogether([Paragraph(title, h2), # Paragraph('No data', h2)])) def addPage(self, title, rows=[1]): self.canvas.showPage() self.canvas.saveState() self.canvas.setLineWidth(2) self.canvas.setStrokeColor(colors.RED) self.canvas.roundRect(self.margin, self.margin, self.width - self.margin*2, self.height - self.margin*2, 20, stroke=1, fill=0) self.canvas.restoreState() self.canvas.setFillColor(colors.GREEN1) self.canvas.setFont("Helvetica-Bold", self.title_height/3) self.canvas.drawString(self.margin*2, self.height - self.margin - 4*self.title_height/5, title) self.canvas.setFont("Helvetica-Bold", self.title_height/3) self.canvas.drawRightString(self.width - self.margin*2, self.height - self.margin - 4*self.title_height/5, self.interval) self.page_num += 1 self.canvas.setFont("Helvetica-Bold", 12) self.canvas.drawCentredString(self.width/2, 0, "Page %d" % self.page_num) self.page_title = title self.page_rows = rows self.page_frags = 0
def render(self, outfile, font_name, font_size): """ Render the binary heat map as a PDF to the file-like object or filename ``outfile``. All text will be typeset in the font named ``font_name`` at size ``font_size``. """ c = Canvas(outfile) c.setFont(font_name, font_size) leftlen = max(map(c.stringWidth, self.row_labels)) + LABEL_PAD * 2 toplen = max(map(c.stringWidth, self.column_labels)) + LABEL_PAD * 2 miny = self.rows * font_size * 1.2 maxx = self.columns * font_size * 1.2 c.setPageSize( (leftlen + maxx + PADDING * 2, miny + toplen + PADDING * 2)) # Set coordinates so that LL corner has coord (-leftlen-PADDING, # -miny-PADDING) and the origin is at the point where the borders of the # row & column labels meet: c.translate(leftlen + PADDING, miny + PADDING) lineheight = font_size * 1.2 radius = lineheight / 3 c.setFillColorRGB(*COL_BG_COLOR) for i in range(0, self.columns, 2): c.rect( i * lineheight, -miny, lineheight, miny + toplen, stroke=0, fill=1, ) c.setFillColorRGB(*ROW_BG_COLOR) for i in range(2, self.rows + 1, 2): # Yes, it starts at 2, so that the positive rectangle height will # make it fill row 1. c.rect( -leftlen, -i * lineheight, leftlen + maxx, lineheight, stroke=0, fill=1, ) c.setFillColorRGB(0, 0, 0) c.line(0, toplen, 0, -miny) c.line(-leftlen, 0, maxx, 0) for i, label in enumerate(self.row_labels): c.drawRightString( -LABEL_PAD, -(i + 1) * lineheight + font_size / 3, label, ) for i, label in enumerate(self.column_labels): c.saveState() c.translate((i + 1) * lineheight, 0) c.rotate(90) c.drawString(LABEL_PAD, font_size / 3, label) c.restoreState() for row, col in self.get_indexed_pairs(): c.circle( (col + 0.5) * lineheight, -(row + 0.5) * lineheight, radius, stroke=0, fill=1, ) c.showPage() c.save()
def _on_first_page(self, canvas: Canvas, doc): canvas.setCreator('pretix.eu') canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) canvas.saveState() canvas.setFont(self.font_regular, 8) if self.invoice.order.testmode: canvas.saveState() canvas.setFont('OpenSansBd', 30) canvas.setFillColorRGB(32, 0, 0) canvas.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, ugettext('TEST MODE')) canvas.restoreState() for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip()) textobject = canvas.beginText(25 * mm, (297 - 15) * mm) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Invoice from').upper()) canvas.drawText(textobject) self._draw_invoice_from(canvas) textobject = canvas.beginText(25 * mm, (297 - 50) * mm) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Invoice to').upper()) canvas.drawText(textobject) self._draw_invoice_to(canvas) textobject = canvas.beginText(125 * mm, (297 - 38) * mm) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Order code').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(self.invoice.order.full_code) canvas.drawText(textobject) textobject = canvas.beginText(125 * mm, (297 - 50) * mm) textobject.setFont(self.font_bold, 8) if self.invoice.is_cancellation: textobject.textLine(pgettext('invoice', 'Cancellation number').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Original invoice').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(self.invoice.refers.number) else: textobject.textLine(pgettext('invoice', 'Invoice number').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(self.invoice.number) textobject.moveCursor(0, 5) if self.invoice.is_cancellation: textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Cancellation date').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Original invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(date_format(self.invoice.refers.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) else: textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Invoice date').upper()) textobject.moveCursor(0, 5) textobject.setFont(self.font_regular, 10) textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT")) textobject.moveCursor(0, 5) canvas.drawText(textobject) if self.invoice.event.settings.invoice_logo_image: logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) ir = ThumbnailingImageReader(logo_file) try: ir.resize(25 * mm, 25 * mm, 300) except: logger.exception("Can not resize image") pass canvas.drawImage(ir, 95 * mm, (297 - 38) * mm, width=25 * mm, height=25 * mm, preserveAspectRatio=True, anchor='n', mask='auto') def shorten(txt): txt = str(txt) p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p_size = p.wrap(65 * mm, 50 * mm) while p_size[1] > 2 * self.stylesheet['Normal'].leading: txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…' p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p_size = p.wrap(65 * mm, 50 * mm) return txt if not self.invoice.event.has_subevents: if self.invoice.event.settings.show_date_to and self.invoice.event.date_to: p_str = ( shorten(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format( from_date=self.invoice.event.get_date_from_display(), to_date=self.invoice.event.get_date_to_display()) ) else: p_str = ( shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display() ) else: p_str = shorten(self.invoice.event.name) p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal']) p.wrapOn(canvas, 65 * mm, 50 * mm) p_size = p.wrap(65 * mm, 50 * mm) p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1]) textobject = canvas.beginText(125 * mm, (297 - 15) * mm) textobject.setFont(self.font_bold, 8) textobject.textLine(pgettext('invoice', 'Event').upper()) canvas.drawText(textobject) canvas.restoreState()
def render(self, outfile, font_name, font_size): """ Render the binary heat map as a PDF to the file-like object or filename ``outfile``. All text will be typeset in the font named ``font_name`` at size ``font_size``. """ c = Canvas(outfile) c.setFont(font_name, font_size) leftlen = max(map(c.stringWidth, self.row_labels)) + LABEL_PAD * 2 toplen = max(map(c.stringWidth, self.column_labels)) + LABEL_PAD * 2 miny = self.rows * font_size * 1.2 maxx = self.columns * font_size * 1.2 c.setPageSize((leftlen + maxx + PADDING*2, miny + toplen + PADDING*2)) # Set coordinates so that LL corner has coord (-leftlen-PADDING, # -miny-PADDING) and the origin is at the point where the borders of the # row & column labels meet: c.translate(leftlen+PADDING, miny+PADDING) lineheight = font_size * 1.2 radius = lineheight / 3 c.setFillColorRGB(*COL_BG_COLOR) for i in range(0, self.columns, 2): c.rect( i * lineheight, -miny, lineheight, miny + toplen, stroke=0, fill=1, ) c.setFillColorRGB(*ROW_BG_COLOR) for i in range(2, self.rows+1, 2): # Yes, it starts at 2, so that the positive rectangle height will # make it fill row 1. c.rect( -leftlen, -i * lineheight, leftlen + maxx, lineheight, stroke=0, fill=1, ) c.setFillColorRGB(0, 0, 0) c.line(0, toplen, 0, -miny) c.line(-leftlen, 0, maxx, 0) for i, label in enumerate(self.row_labels): c.drawRightString( -LABEL_PAD, -(i+1) * lineheight + font_size / 3, label, ) for i, label in enumerate(self.column_labels): c.saveState() c.translate((i+1) * lineheight, 0) c.rotate(90) c.drawString(LABEL_PAD, font_size / 3, label) c.restoreState() for row, col in self.get_indexed_pairs(): c.circle( (col+0.5) * lineheight, -(row+0.5) * lineheight, radius, stroke=0, fill=1, ) c.showPage() c.save()
class Reporter(object): def __init__(self,vapp): self.dataApp = vapp path = self.dataApp.repoPath + self.dataApp.rdataName + '.pdf' self.canvas = Canvas(path) self.page = 1 def header(self): self.canvas.setFont("Helvetica", 10) self.canvas.drawCentredString(4.135*inch, 10.74*inch, 'Copyright@2015 : ycroft.net') self.canvas.setFont("Helvetica", 11.5) self.canvas.line(1*inch, 10.69*inch, 7.27*inch, 10.69*inch) def footer(self): self.canvas.setFont("Helvetica", 11.5) self.canvas.line(1*inch, 1*inch, 7.27*inch, 1*inch) self.canvas.setFont("Helvetica", 10) self.canvas.drawCentredString(4.135*inch, 0.83*inch, '- '+str(self.page)+' -') def cover(self,coverInfo): dataName = coverInfo.get('dataName','no name') author = coverInfo.get('author','no name') version = coverInfo.get('version','unknown') self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 40) self.canvas.drawCentredString(4.135*inch, 7.5*inch, 'Analysis Report') self.canvas.setFont("Helvetica", 20) self.canvas.drawCentredString(4.135*inch, 6.8*inch, 'for data \'' + dataName + '\'') self.canvas.setFont("Helvetica", 15) self.canvas.drawRightString(3.935*inch, 4.4*inch, 'author:') self.canvas.drawRightString(3.935*inch, 3.9*inch, 'date:') self.canvas.drawRightString(3.935*inch, 3.4*inch, 'version:') self.canvas.drawString(4.335*inch, 4.4*inch, author) self.canvas.drawString(4.335*inch, 3.9*inch, str(datetime.now().strftime('%a, %b %d %H:%M'))) self.canvas.drawString(4.335*inch, 3.4*inch, version) self.canvas.showPage() self.page += 1 def body(self): self.header() self.footer() sdataName = self.dataApp.sdataName rdataName = self.dataApp.rdataName imgPath = './spec_data/img/' self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'I. Modulation Factors ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'These factors are derived from the file \''+sdataName+'\'') self.canvas.drawInlineImage(imgPath + sdataName + '_cs0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + sdataName + '_cs1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + sdataName + '_cs2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + sdataName + '_cs3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'II. Measured Data & FFT ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'The data is derived from the file \''+rdataName+'\', and each fft channel has been filtered.') self.canvas.drawInlineImage(imgPath + rdataName + '_rd.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fft.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'III. Modulation Signals ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'These signals are derived by ifft on the corresponding channel.') self.canvas.drawInlineImage(imgPath + rdataName + '_fa0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fa1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + rdataName + '_fa2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fa3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'IV. Stokes Vectors ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This can be figured out using modulation signals and modulation factors.') self.canvas.drawInlineImage(imgPath + rdataName + '_s0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_s1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + rdataName + '_s2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_s3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'IV. Degree of Polarization ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This was figured out using four Stokes vectors.') self.canvas.drawInlineImage(imgPath + rdataName + '_dop.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() windows = self.dataApp.windows self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'V. Data Analysis ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This was automatically generated by program.') self.canvas.drawString(1.5*inch, 9.0*inch, '-The number of the peaks recognized in `FFT` datagram:') self.canvas.drawString(2.0*inch, 8.7*inch, str(len(windows)) + ' peaks') self.canvas.drawString(1.5*inch, 8.4*inch, '-The range of the peaks recognized in `FFT` datagram:') for i in range(0,len(windows)): self.canvas.drawString(2.0*inch, (8.1-i*0.3)*inch, '[' + str(i)+ '] ' +str(windows[i][0])) self.canvas.drawString(3.9*inch, (8.1-i*0.3)*inch, '~ ' + str(windows[i][1])) self.canvas.showPage() self.page += 1 def gen(self): self.cover({ 'dataName' : self.dataApp.rdataName + '`C spec', 'author' : 'ycroft', 'version' : 'v0.1' }) self.body() self.canvas.save()
def generate(self, output_path): if output_path == None: print("no output path specified") return canvas = Canvas(output_path, pagesize=A4) canvas.setFont("Helvetica", 7) page_width, page_height = A4 top_margin = 1.3 * cm side_margin = 0.4 * cm label_width = 4.95 * cm label_height = 2.9 * cm vertical_pitch = 3 * cm horizontal_pitch = 5.05 * cm image_width = 0.7 * label_width image_height = (2 / 3) * label_height across = 4 down = 9 label_x_start = side_margin label_y_start = page_height - top_margin - label_height image_x_start = label_x_start + (label_width - image_width) / 2 image_y_start = label_y_start + (label_height * 0.25) sku_x_start = label_x_start + label_width * 0.04 sku_y_start = label_y_start + label_height * 0.04 + label_height * 0.12 product_x_start = sku_x_start product_y_start = label_y_start + label_height * 0.04 size_x_start = horizontal_pitch size_y_start = sku_y_start design_x_start = size_x_start design_y_start = product_y_start season_x_start = label_width / 2 + side_margin season_y_start = product_y_start sheets_needed = math.ceil(len(self.csv_data) / 36) while sheets_needed >= 1: canvas.setFont("Helvetica", 7) for i in range(down): for j in range(across): if len(self.csv_data) < 1: break data = self.csv_data.pop(0) adjust_x = j * horizontal_pitch adjust_y = i * vertical_pitch # border #x = label_x_start + adjust_x #y = label_y_start - adjust_y #canvas.rect(x, y, label_width, label_height, stroke=1, fill=0) image_x = image_x_start + adjust_x image_y = image_y_start - adjust_y canvas.drawImage(self.createBarcode(data['barcode']), image_x, image_y, width=image_width, height=image_height, mask='auto') #canvas.draw(self.createBarcode(data['barcode']), image_x, image_y, width=image_width, height=image_height, mask='auto') sku_x = sku_x_start + adjust_x sku_y = sku_y_start - adjust_y canvas.drawString(sku_x, sku_y, data['sku']) product_x = product_x_start + adjust_x product_y = product_y_start - adjust_y canvas.drawString(product_x, product_y, data['product']) size_x = size_x_start + adjust_x size_y = size_y_start - adjust_y canvas.drawRightString(size_x, size_y, data['size']) design_x = design_x_start + adjust_x design_y = design_y_start - adjust_y canvas.drawRightString( design_x, design_y, data['design'][:12] if len(data['design']) > 12 else data['design']) season_x = season_x_start + adjust_x season_y = season_y_start - adjust_y canvas.drawCentredString(season_x, season_y, data['season']) sheets_needed -= 1 canvas.showPage() canvas.save() print(output_path + " saved")