def _get_output_page(self, output_infos): inch = 72 buf = io.BytesIO() canvas = Canvas(buf, pagesize=(8.5*inch, 11*inch)) for info in output_infos: canvas.saveState() x, y = info.translate # We flip the y coordinate since that's how PDF programs give us # the number of pixels from the top, not the bottom. y = 11*inch - y canvas.translate(x, y) if info.rotate != 0: canvas.rotate(info.rotate) t = canvas.beginText() t.setFont('Courier', 10) t.setTextOrigin(0, 0) t.textLines(info.text) canvas.drawText(t) canvas.restoreState() canvas.save() return PdfFileReader(buf).getPage(0)
def generatePDF(): canvas = Canvas("bamreport.pdf") user_in_lines = user_in.split('\n') wrapper = TextWrapper() user_in_wrapped_lines = list() for line in user_in_lines: user_in_wrapped_lines += wrapper.wrap(line) count = 0 text_object = canvas.beginText(100, 741.89) for line in user_in_wrapped_lines: text_object.textLine(line) count += 1 if count == 45: canvas.drawText(text_object) canvas.showPage() text_object = canvas.beginText(100, 741.89) count = 0 canvas.drawText(text_object) # Save the pdf file canvas.showPage() canvas.save()
def result2pdf(result, reportfilename): '''Write HDR 2nd check output to a PDF report. Input: list of strings (report text).''' # Lines per page lpp = 48 # Pages needed in report pages = ceil(len(result) / float(lpp)) print '# of pages:', pages pdf = Canvas(reportfilename, pagesize=letter) report = pdf.beginText(inch * 1, inch * 10) # Single page report if len(result) < lpp: for line in result: report.textLine(line) pdf.drawText(report) pdf.showPage() # Or create a multi-page report else: page = 1 l = 0 while page < pages: # Reset page contents report = pdf.beginText(inch * 1, inch * 10) while l < lpp * page: print 'l:', l report.textLine(result[l]) l += 1 pdf.drawText(report) pdf.showPage() page += 1 # Print last page # Reset page contents report = pdf.beginText(inch * 1, inch * 10) for line in result[int(pages - 1) * lpp:]: report.textLine(line) pdf.drawText(report) pdf.showPage() pdf.save()
def result2pdf(result,reportfilename): '''Write HDR 2nd check output to a PDF report. Input: list of strings (report text).''' # Lines per page lpp = 48 # Pages needed in report pages = ceil(len(result)/float(lpp)) print '# of pages:',pages pdf = Canvas(reportfilename, pagesize = letter) report = pdf.beginText(inch * 1, inch * 10) # Single page report if len(result) < lpp: for line in result: report.textLine(line) pdf.drawText(report) pdf.showPage() # Or create a multi-page report else: page = 1 l = 0 while page < pages: # Reset page contents report = pdf.beginText(inch * 1, inch * 10) while l < lpp*page: print 'l:',l report.textLine(result[l]) l += 1 pdf.drawText(report) pdf.showPage() page += 1 # Print last page # Reset page contents report = pdf.beginText(inch * 1, inch * 10) for line in result[int(pages-1)*lpp:]: report.textLine(line) pdf.drawText(report) pdf.showPage() pdf.save()
class pdf: def __init__(self, name, logo): self.text = None self.name = name self.canvas = Canvas(self.name + ".pdf") self.logo = logo from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont pdfmetrics.registerFont(TTFont('times', 'times.ttf')) pdfmetrics.registerFont(TTFont('timesb', 'timesbd.ttf')) if self.logo == "logo.png": self.canvas.drawImage(self.logo, 50, 700, mask="auto") def write_string(self, txt, x, y, font, size): self.canvas.setFont(font, size) self.canvas.drawString(x, y, txt) def write_text(self, txt, x, y, font, size): self.canvas.setFont(font, size) self.text = self.canvas.beginText(x, y) self.text.setFont(font, size) self.text.textLines(txt) self.canvas.drawText(self.text) def save(self): self.canvas.save()
def generate_pdf_file(request): buf = io.BytesIO() c = Canvas(buf, pagesize=letter, bottomup=0) # Create a Text Object textobj = c.beginText() textobj.setTextOrigin(inch, inch) textobj.setFont("Helvetica", 14) lines = [] item_list = TaskModel.objects.filter(user=request.user.id) for item in item_list: if item.complete == True: lines.append(f"Task Name: {item.title}") lines.append("Status: Completed!") lines.append(" ") else: lines.append(f"Task Name: {item.title}") lines.append("Status: Not Completed!") lines.append(" ") for line in lines: textobj.textLine(line) c.drawText(textobj) c.showPage() c.save() buf.seek(0) return FileResponse(buf, as_attachment=True, filename="generated_task_list.pdf")
def _get_output_page(self, output_infos): inch = 72 buf = io.BytesIO() canvas = Canvas(buf, pagesize=(8.5 * inch, 11 * inch)) for info in output_infos: canvas.saveState() x, y = info.translate # We flip the y coordinate since that's how PDF programs give us # the number of pixels from the top, not the bottom. y = 11 * inch - y canvas.translate(x, y) if info.rotate != 0: canvas.rotate(info.rotate) t = canvas.beginText() t.setFont('Courier', 10) t.setTextOrigin(0, 0) t.textLines(info.text) canvas.drawText(t) canvas.restoreState() canvas.save() return PdfFileReader(buf).getPage(0)
def __create_pdf_template(self, filepath, img, countries, timespan, pagesize): canvas = Canvas(filepath, pagesize=pagesize) canvas.setFont("Helvetica", 20) title = self.__title subtitle = "(Generated: " + self.__subtitle title_magic_offset, subtitle_magic_offset, img_magic_offset = 70, 100, 650 title_x, title_y = A4[0] / 2, A4[1] - title_magic_offset subtitle_x, subtitle_y = A4[0] / 2, A4[1] - subtitle_magic_offset img_x, img_y = 0, A4[1] - img_magic_offset canvas.drawCentredString(title_x, title_y, title) canvas.setFont("Helvetica", 12) canvas.drawCentredString(subtitle_x, subtitle_y, subtitle) canvas.drawImage(img, img_x, img_y, A4[0], A4[1] / 2) countries_wrap = "\n".join(wrap(countries, 70)) countries_text = canvas.beginText(A4[0] - 450, A4[1] - 180) for line in countries_wrap.splitlines(False): countries_text.textLine(line.rstrip()) canvas.drawText(countries_text) timespan_end = ' - '.join(timespan) timespan = "Timespan: " + timespan_end canvas.drawCentredString(A4[0] / 2, A4[1] - 150, timespan) return canvas
def writePDF(drawings): "Create and save a PDF file containing some drawings." pdfPath = os.path.splitext(sys.argv[0])[0] + '.pdf' c = Canvas(pdfPath) c.setFont(_FONTS[0], 32) c.drawString(80, 750, 'ReportLab Graphics-Shapes Test') # Print drawings in a loop, with their doc strings. c.setFont(_FONTS[0], 12) y = 740 i = 1 for (drawing, docstring, funcname) in drawings: if y < 300: # Allows 5-6 lines of text. c.showPage() y = 740 # Draw a title. y = y - 30 c.setFont(_FONTS[2], 12) c.drawString(80, y, '%s (#%d)' % (funcname, i)) c.setFont(_FONTS[0], 12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height drawing.drawOn(c, 80, y) i = i + 1 c.save() print 'wrote %s ' % pdfPath
def pdf_output(request): """PDF output for orders.""" # Create a file-like buffer to receive PDF data. buffer = io.BytesIO() canvas = Canvas(buffer, "canvas.pdf") pdfmetrics.registerFont(TTFont('DejaVu', 'DejaVuSansCondensed.ttf')) canvas.setFont('DejaVu', 10) orders = Order.objects.all() order_items = OrderItem.objects.all() text_lines = [] for order in orders: text_lines.append('Имя : {0}'.format(order.first_name)) text_lines.append('Фамилия : {0}'.format(order.last_name)) text_lines.append('Email : {0}'.format(order.email)) text_lines.append('Адреы : {0}'.format(order.address)) text_lines.append('Индекс : {0}'.format(order.postal_code)) text_lines.append('Город : {0}'.format(order.city)) text_lines.append('Заказ создан : {0}'.format(order.created)) text_lines.append('Заказ изменен : {0}'.format(order.updated)) text_lines.append('Оплата : {0}'.format(order.paid)) text_lines.append('Товары : ') for item in order_items: if item.order_id == order.id: k = str(item.product) text_lines.append(k) text_lines.append('*'*55) text = canvas.beginText(30, 740) for text_line in text_lines: text.textLine(text_line) canvas.drawText(text) canvas.save() buffer.seek(0) return FileResponse(buffer, as_attachment=True, filename='canvas.pdf')
def writePDF(drawings): "Create and save a PDF file containing some drawings." pdfPath = os.path.splitext(sys.argv[0])[0] + '.pdf' c = Canvas(pdfPath) c.setFont(_FONTS[0], 32) c.drawString(80, 750, 'ReportLab Graphics-Shapes Test') # Print drawings in a loop, with their doc strings. c.setFont(_FONTS[0], 12) y = 740 i = 1 for (drawing, docstring, funcname) in drawings: if y < 300: # Allows 5-6 lines of text. c.showPage() y = 740 # Draw a title. y = y - 30 c.setFont(_FONTS[2],12) c.drawString(80, y, '%s (#%d)' % (funcname, i)) c.setFont(_FONTS[0],12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height drawing.drawOn(c, 80, y) i = i + 1 c.save() print 'wrote %s ' % pdfPath
def do(self, name: str, hocr_list: list, images: list) -> str: """ Cria um pdf searchable combinando imagens com hocr """ pdf_path = self.searchable_path + name + "_searchable.pdf" pdf = Canvas(pdf_path) pdf.setCreator('TotOcr') pdf.setTitle(name) dpi = 300 p1 = re.compile(r'bbox((\s+\d+){4})') p2 = re.compile(r'baseline((\s+[\d\.\-]+){2})') for img_path, hocr in zip(images, hocr_list): img = Image.open(img_path) w, h = img.size width = w * 72 / dpi height = h * 72 / dpi pdf.setPageSize((width, height)) pdf.drawImage(img_path, 0, 0, width=width, height=height) hocr_et = etree.fromstring(hocr) img.close() #Draw a text layer for OCR data for line in hocr_et.xpath('//*[@class="ocr_line"]'): linebox = p1.search(line.attrib['title']).group(1).split() try: baseline = p2.search(line.attrib['title']).group(1).split() except AttributeError: baseline = [0, 0] linebox = [float(i) for i in linebox] baseline = [float(i) for i in baseline] xpath_elements = './/*[@class="ocrx_word"]' if (not (line.xpath('boolean(' + xpath_elements + ')'))): # if there are no words elements present, # we switch to lines as elements xpath_elements = '.' for word in line.xpath(xpath_elements): rawtext = word.text.strip() if rawtext == '': continue font_width = pdf.stringWidth(rawtext, 'invisible', 8) if font_width <= 0: continue box = p1.search(word.attrib['title']).group(1).split() box = [float(i) for i in box] b = (((box[0] + box[2]) / 2 - linebox[0]) * baseline[0] + baseline[1]) + linebox[3] text = pdf.beginText() text.setTextRenderMode(3) # double invisible text.setFont('invisible', 8) text.setTextOrigin(box[0] * 72 / dpi, height - b * 72 / dpi) box_width = (box[2] - box[0]) * 72 / dpi text.setHorizScale(100.0 * box_width / font_width) text.textLine(rawtext) pdf.drawText(text) pdf.showPage() pdf.save() return pdf_path
def create(self, file_name): bill_canvas = Canvas("hello.pdf", pagesize=letter, bottomup=0) text_object = bill_canvas.beginText(inch, inch) text_object.textLine("Bill example") print('data is', self.invoice.goods) for index, good in enumerate(self.invoice.goods): text_object.textLine(" {}. {} {} {}".format( index + 1, good.title, good.units, good.price)) text_object.textLine("................") bill_canvas.drawText(text_object) bill_canvas.save()
def generate_pdf(): buffer = BytesIO() canvas = Canvas(buffer, pagesize=A4) textobject = canvas.beginText(1.5, -2.5) textobject.textLine("this is a test") canvas.saveState() canvas.save() pdf = buffer.getvalue() buffer.close() return pdf
def test(outDir='pdfout', shout=False): from reportlab.graphics.shapes import _baseGFontName, _baseGFontNameBI from reportlab.rl_config import verbose import os if not os.path.isdir(outDir): os.mkdir(outDir) fn = os.path.join(outDir, 'renderPDF.pdf') c = Canvas(fn) c.setFont(_baseGFontName, 36) c.drawString(80, 750, 'Graphics Test') # print all drawings and their doc strings from the test # file #grab all drawings from the test module from reportlab.graphics import testshapes drawings = [] for funcname in dir(testshapes): if funcname[0:10] == 'getDrawing': func = getattr(testshapes, funcname) drawing = func() #execute it docstring = getattr(func, '__doc__', '') drawings.append((drawing, docstring)) #print in a loop, with their doc strings c.setFont(_baseGFontName, 12) y = 740 i = 1 for (drawing, docstring) in drawings: assert (docstring is not None), "Drawing %d has no docstring!" % i if y < 300: #allows 5-6 lines of text c.showPage() y = 740 # draw a title y = y - 30 c.setFont(_baseGFontNameBI, 12) c.drawString(80, y, 'Drawing %d' % i) c.setFont(_baseGFontName, 12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height draw(drawing, c, 80, y) i = i + 1 if y != 740: c.showPage() c.save() if shout or verbose > 2: print('saved %s' % ascii(fn))
def json_to_pdf(links_json): buffer = io.BytesIO() p = Canvas(buffer, bottomup=0) # p = Canvas(filename, bottomup=0) textobject = p.beginText() textobject.setTextOrigin(inch, inch) textobject.setFont("Helvetica-Oblique", 14) for link in links_json: textobject.textLine(link) p.drawText(textobject) p.showPage() p.save() buffer.seek(0) return buffer
def test(outDir='pdfout',shout=False): from reportlab.graphics.shapes import _baseGFontName, _baseGFontNameBI from reportlab.rl_config import verbose import os if not os.path.isdir(outDir): os.mkdir(outDir) fn = os.path.join(outDir,'renderPDF.pdf') c = Canvas(fn) c.setFont(_baseGFontName, 36) c.drawString(80, 750, 'Graphics Test') # print all drawings and their doc strings from the test # file #grab all drawings from the test module from reportlab.graphics import testshapes drawings = [] for funcname in dir(testshapes): if funcname[0:10] == 'getDrawing': drawing = eval('testshapes.' + funcname + '()') #execute it docstring = eval('testshapes.' + funcname + '.__doc__') drawings.append((drawing, docstring)) #print in a loop, with their doc strings c.setFont(_baseGFontName, 12) y = 740 i = 1 for (drawing, docstring) in drawings: assert (docstring is not None), "Drawing %d has no docstring!" % i if y < 300: #allows 5-6 lines of text c.showPage() y = 740 # draw a title y = y - 30 c.setFont(_baseGFontNameBI,12) c.drawString(80, y, 'Drawing %d' % i) c.setFont(_baseGFontName,12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height draw(drawing, c, 80, y) i = i + 1 if y!=740: c.showPage() c.save() if shout or verbose>2: print('saved %s' % ascii(fn))
def create_pdf(filename, budgets): w, h = A4 canvas = Canvas('/tmp/' + filename, pagesize=A4) canvas.setFont('Helvetica', 14) textobject = canvas.beginText(50, h - 50) textobject.textLine('Creado el: ' + filename.replace('pdf', '')) textobject.moveCursor(125, 10) textobject.textLine('Presupuesto de Tratamientos EDENT') textobject.moveCursor(-75, 100) for budget in budgets: textobject.textLine(budget['name'] + ' : Q' + budget['price']) textobject.moveCursor(0, 15) textobject.moveCursor(250, 30) textobject.textLine('Total: Q' + str(get_total(budgets))) canvas.drawText(textobject) canvas.save()
def sodelovanja(request): sodelovanja = Sodelovanje.objects.all() person_form = PersonForm() if request.method == 'POST': form = SodelovanjeFilter(request.POST) if form.is_valid(): for key, value in form.cleaned_data.items(): ##'**' rabis zato da ti python resolva spremenljivke (as opposed da passa dobesedni string) if value and key != 'export': sodelovanja = sodelovanja.filter(**{key: value}) else: form = SodelovanjeFilter() try: export = form.cleaned_data['export'] if export: from reportlab.pdfgen.canvas import Canvas output = StringIO() if export == 'txt': for i in sodelovanja: output.write("%s\n" % i) elif export == 'pdf': pdf = Canvas(output) rhyme = pdf.beginText(30, 200) for i in sodelovanja: rhyme.textLine(i.__unicode__()) pdf.drawText(rhyme) pdf.showPage() pdf.save() elif export == 'csv': for i in sodelovanja: output.write("%s\n" % i) response = HttpResponse(mimetype='application/octet-stream') response['Content-Disposition'] = "attachment; filename=" + 'export.' + export response.write(output.getvalue()) return response except AttributeError: pass return render_to_response('org/sodelovanja.html', {'sodelovanja': sodelovanja, 'form': form, 'admin_org': '%s/intranet/admin/org/' % settings.BASE_URL, 'person_form': person_form}, context_instance=RequestContext(request))
class PdfDocument(object): CENTER = 'center' RIGHT = 'right' LEFT = 'left' ALIGN = { CENTER: 'Centred', RIGHT: 'Right' } def __init__(self, instream, outstream, font=("Takao", 9)): self.base = PdfFileReader(instream) self.s = BytesIO() self.c = Canvas(self.s, pagesize=A4) self.font = font self.c.setFont(*self.font) self.output = outstream def string(self, pos, t, align=LEFT): getattr(self.c, 'draw%sString' % self.ALIGN.get(align, ''))(*pos, t) def circle(self, pos): self.c.circle(*pos, r=10, stroke=1, fill=0) def text(self, pos, txt, **kwargs): t = self.c.beginText() t.setTextOrigin(*pos) t.textLines(txt) self.c.drawText(t) def nextpage(self): self.c.showPage() self.c.setFont(*self.font) def write(self): self.c.save() self.s.seek(0) inp = PdfFileReader(self.s) out = PdfFileWriter() for i in range(min(inp.getNumPages(), self.base.getNumPages())): p = self.base.getPage(i) p.mergePage(inp.getPage(i)) out.addPage(p) out.write(self.output)
def test(): from reportlab.graphics.shapes import _baseGFontName, _baseGFontNameBI c = Canvas("renderPDF.pdf") c.setFont(_baseGFontName, 36) c.drawString(80, 750, "Graphics Test") # print all drawings and their doc strings from the test # file # grab all drawings from the test module from reportlab.graphics import testshapes drawings = [] for funcname in dir(testshapes): if funcname[0:10] == "getDrawing": drawing = eval("testshapes." + funcname + "()") # execute it docstring = eval("testshapes." + funcname + ".__doc__") drawings.append((drawing, docstring)) # print in a loop, with their doc strings c.setFont(_baseGFontName, 12) y = 740 i = 1 for (drawing, docstring) in drawings: assert docstring is not None, "Drawing %d has no docstring!" % i if y < 300: # allows 5-6 lines of text c.showPage() y = 740 # draw a title y = y - 30 c.setFont(_baseGFontNameBI, 12) c.drawString(80, y, "Drawing %d" % i) c.setFont(_baseGFontName, 12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height draw(drawing, c, 80, y) i = i + 1 if y != 740: c.showPage() c.save() print("saved renderPDF.pdf")
def save_pdf(self, filename, margins=(1, 1)): ''' Make and save a PDF of this coverage plot, including a legend. Margins are expressed in inches: (top-bottom, left-right). ''' from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter from reportlab.pdfgen.canvas import Canvas c = Canvas(filename, pagesize=letter) # Compute margins. margin_top, margin_left = margins margin_top *= inch margin_left *= inch whole_page_width, whole_page_height = letter page_top = whole_page_height - margin_top page_left = margin_left page_width = whole_page_width - 2 * margin_left # Show the main image. image = self.img image_width = page_width image_height = image_width / image.size[0] * image.size[1] image_x = page_left image_y = page_top - image_height c.drawInlineImage(image, image_x, image_y, width=image_width, height=image_height) # Draw legends beneath the image. textobject = c.beginText() textobject.setTextOrigin(page_left, image_y - .5 * inch) textobject.setFont('Helvetica', 14) for name, color in izip(self.names, self.colors): textobject.setFillColorRGB(*color) textobject.textLine(name) c.drawText(textobject) # Done. c.showPage() c.save()
def test_simulated_scan(outdir): canvas = Canvas( fspath(outdir / 'fakescan.pdf'), pagesize=(209.8, 297.6), ) page_vars = [(2, 36, 250), (91, 170, 240), (179, 190, 36), (271, 36, 36)] for n, page_var in enumerate(page_vars): text = canvas.beginText() text.setFont('Helvetica', 20) angle, x, y = page_var cos_a, sin_a = cos(angle / 180.0 * pi), sin(angle / 180.0 * pi) text.setTextTransform(cos_a, -sin_a, sin_a, cos_a, x, y) text.textOut(f'Page {n + 1}') canvas.drawText(text) canvas.showPage() canvas.save() check_ocrmypdf( outdir / 'fakescan.pdf', outdir / 'out.pdf', '--force-ocr', '--deskew', '--rotate-pages', '--plugin', 'tests/plugins/tesseract_debug_rotate.py', ) with pikepdf.open(outdir / 'out.pdf') as pdf: assert ( pdf.pages[1].MediaBox[2] > pdf.pages[1].MediaBox[3] ), "Wrong orientation: not landscape" assert ( pdf.pages[3].MediaBox[2] > pdf.pages[3].MediaBox[3] ), "Wrong orientation: Not landscape" assert ( pdf.pages[0].MediaBox[2] < pdf.pages[0].MediaBox[3] ), "Wrong orientation: Not portrait" assert ( pdf.pages[2].MediaBox[2] < pdf.pages[2].MediaBox[3] ), "Wrong orientation: Not portrait"
def test_single_page_text(): filename = os.path.join(TEST_OUTPUT, "text.pdf") pdf = Canvas(filename, pagesize=(8 * 72, 6 * 72)) text = pdf.beginText() text.setFont("Helvetica", 12) text.setTextOrigin(1 * 72, 3 * 72) text.textLine("Methink'st thou art a general offence and every" " man should beat thee.") pdf.drawText(text) pdf.showPage() pdf.save() pdfinfo = pageinfo.pdf_get_all_pageinfo(filename) assert len(pdfinfo) == 1 page = pdfinfo[0] assert page["has_text"] assert len(page["images"]) == 0
def test(): from reportlab.graphics.shapes import _baseGFontName, _baseGFontNameBI c = Canvas('renderPDF.pdf') c.setFont(_baseGFontName, 36) c.drawString(80, 750, 'Graphics Test') # print all drawings and their doc strings from the tests # file #grab all drawings from the tests module from reportlab.graphics import testshapes drawings = [] for funcname in dir(testshapes): if funcname[0:10] == 'getDrawing': drawing = eval('testshapes.' + funcname + '()') #execute it docstring = eval('testshapes.' + funcname + '.__doc__') drawings.append((drawing, docstring)) #print in a loop, with their doc strings c.setFont(_baseGFontName, 12) y = 740 i = 1 for (drawing, docstring) in drawings: assert (docstring is not None), "Drawing %d has no docstring!" % i if y < 300: #allows 5-6 lines of text c.showPage() y = 740 # draw a title y = y - 30 c.setFont(_baseGFontNameBI, 12) c.drawString(80, y, 'Drawing %d' % i) c.setFont(_baseGFontName, 12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height draw(drawing, c, 80, y) i = i + 1 if y != 740: c.showPage() c.save() print 'saved renderPDF.pdf'
def test_single_page_text(outdir): filename = outdir / 'text.pdf' pdf = Canvas(str(filename), pagesize=(8 * 72, 6 * 72)) text = pdf.beginText() text.setFont('Helvetica', 12) text.setTextOrigin(1 * 72, 3 * 72) text.textLine("Methink'st thou art a general offence and every" " man should beat thee.") pdf.drawText(text) pdf.showPage() pdf.save() info = pdfinfo.PdfInfo(filename) assert len(info) == 1 page = info[0] assert page.has_text assert len(page.images) == 0
def test_single_page_text(): filename = os.path.join(TEST_OUTPUT, 'text.pdf') pdf = Canvas(filename, pagesize=(8 * 72, 6 * 72)) text = pdf.beginText() text.setFont('Helvetica', 12) text.setTextOrigin(1 * 72, 3 * 72) text.textLine("Methink'st thou art a general offence and every" " man should beat thee.") pdf.drawText(text) pdf.showPage() pdf.save() pdfinfo = pageinfo.pdf_get_all_pageinfo(filename) assert len(pdfinfo) == 1 page = pdfinfo[0] assert page['has_text'] assert len(page['images']) == 0
def test(): c = Canvas('renderPDF.pdf') c.setFont('Times-Roman', 36) c.drawString(80, 750, 'Graphics Test') # print all drawings and their doc strings from the test # file #grab all drawings from the test module from reportlab.graphics import testshapes drawings = [] for funcname in dir(testshapes): if funcname[0:10] == 'getDrawing': drawing = eval('testshapes.' + funcname + '()') #execute it docstring = eval('testshapes.' + funcname + '.__doc__') drawings.append((drawing, docstring)) #print in a loop, with their doc strings c.setFont('Times-Roman', 12) y = 740 i = 1 for (drawing, docstring) in drawings: assert (docstring is not None), "Drawing %d has no docstring!" % i if y < 300: #allows 5-6 lines of text c.showPage() y = 740 # draw a title y = y - 30 c.setFont('Times-BoldItalic',12) c.drawString(80, y, 'Drawing %d' % i) c.setFont('Times-Roman',12) y = y - 14 textObj = c.beginText(80, y) textObj.textLines(docstring) c.drawText(textObj) y = textObj.getY() y = y - drawing.height draw(drawing, c, 80, y) i = i + 1 if y!=740: c.showPage() c.save() print 'saved renderPDF.pdf'
def test_single_page_text(outdir): filename = outdir / 'text.pdf' pdf = Canvas(str(filename), pagesize=(8*72, 6*72)) text = pdf.beginText() text.setFont('Helvetica', 12) text.setTextOrigin(1*72, 3*72) text.textLine("Methink'st thou art a general offence and every" " man should beat thee.") pdf.drawText(text) pdf.showPage() pdf.save() info = pdfinfo.PdfInfo(filename) assert len(info) == 1 page = info[0] assert page.has_text assert len(page.images) == 0
def make_pdf(name, nome_musica, letra): ''' str -> none Takes in a string text and creates a pdf file named file_name containing the file. >>> make_pdf("Hello world!") >>> >>>a = "Meu coracao nao sei porque, bate feliz quando te ve" >>>make_pdf(a) >>> ''' pdf = Canvas(nome_musica+".pdf") pdf.setFillColorRGB(1, 0, 0) pdf.setStrokeColorRGB(1, 0, 0) ## An important thing to note here is that when specifying coordinates,the ## origin is in the lower left hand corner of the page, rather than the ## top left. The default unit of measurement is a point, equal to one ## seventy-second of an inch. pdf.setFont("Courier", 45) pdf.drawString(cm * 5, cm * 25, name) pdf.setFont("Courier", 30) text = pdf.beginText(cm * 5, cm * 20) for each in range(letra.count("\n")): text.textLine(letra.split("\n")[each]) pdf.drawText(text) ## Close the page. The showPage method closes the current page. ## Any further drawing will occur on the next page pdf.showPage() ## The ReportLab Toolkit saves our page pdf.save()
def image_to_one_page_ocred_pdf(cls, im: Image.Image, pdf_path: str, pdf_width: int, pdf_height: int, ocr_text: List[Dict], font_name: str = "Helvetica") -> None: """Convert the image into a pdf with added textual layer and store it to disc. Run tesseract OCR and add invisible textual content so that the pdf is searchable / clickable. :param im: input image :param pdf_path: path to output pdf :param pdf_width: widht of the pdf to be created (points) :param pdf_height: height of the pdf to be created (points) :param ocr_text: information about words and their bounding boxes in relative coordinates (such as the output of `ocr_one_image`) :param font_name """ new_pdf = Canvas(pdf_path, pagesize=(pdf_width, pdf_height)) new_pdf.drawImage(ImageReader(im), 0, 0, width=pdf_width, height=pdf_height) for word_and_position in ocr_text: word = word_and_position["word"] bb = word_and_position["bb"].rescale(multiply_width_by=pdf_width, multiply_height_by=pdf_height) text = new_pdf.beginText() text.setFont(font_name, bb.height) text.setTextRenderMode(3) # invisible text.setTextOrigin(bb.x_min, pdf_height - bb.y_max) # bottom-left corner text.setHorizScale(100 * bb.width / new_pdf.stringWidth(word, font_name, bb.height)) text.textLine(word) new_pdf.drawText(text) new_pdf.save()
def pdf_demo_10(file): c = Canvas(file, pagesize=A4) text = c.beginText() text.setTextOrigin(20 * mm, 277 * mm) text.setFont(psfontname="Times-Roman", size=12, leading=24) text.textOut("Text which stays on same line. ") text.textOut("More text. ") text.textLine("A line that will drop to next line. ") text.textLine( "A very long line with several sentences but no newline characters. " * 3) text.textLine( "A paragraph with several sentences and newline characters.\n" * 3) text.textLines( "This is text with fifty sentences and newline characters.\n" * 50) c.drawText(text) c.drawCentredString(105 * mm, 10 * mm, "Page 1") c.showPage() c.drawCentredString(105 * mm, 10 * mm, "Page 2") c.save()
def save_pdf(self, filename, margins=(1,1)): ''' Make and save a PDF of this coverage plot, including a legend. Margins are expressed in inches: (top-bottom, left-right). ''' from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter from reportlab.pdfgen.canvas import Canvas c = Canvas(filename, pagesize=letter) # Compute margins. margin_top, margin_left = margins margin_top *= inch; margin_left *= inch whole_page_width, whole_page_height = letter page_top = whole_page_height - margin_top page_left = margin_left page_width = whole_page_width - 2*margin_left # Show the main image. image = self.img image_width = page_width image_height = image_width / image.size[0] * image.size[1] image_x = page_left image_y = page_top - image_height c.drawInlineImage(image, image_x, image_y, width=image_width, height=image_height) # Draw legends beneath the image. textobject = c.beginText() textobject.setTextOrigin(page_left, image_y - .5*inch) textobject.setFont('Helvetica', 14) for name, color in izip(self.names, self.colors): textobject.setFillColorRGB(*color) textobject.textLine(name) c.drawText(textobject) # Done. c.showPage() c.save()
def to_pdf(self, imageFileName, outFileName, fontname="Courier", fontsize=8): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ if self.hocr is None: # warn that no text will be embedded in the output PDF print "Warning: No hOCR file specified. PDF will be image-only." im = Image.open(imageFileName) imwidthpx, imheightpx = im.size if 'dpi' in im.info: width = float(im.size[0]) / im.info['dpi'][0] height = float(im.size[1]) / im.info['dpi'][1] else: # we have to make a reasonable guess # set to None for now and try again using info from hOCR file width = height = None ocr_dpi = (300, 300) # a default, in case we can't find it # get dimensions of the OCR, which may not match the image if self.hocr is not None: for div in self.hocr.findall(".//%sdiv" % (self.xmlns)): if div.attrib['class'] == 'ocr_page': coords = self.element_coordinates(div) ocrwidth = coords[2] - coords[0] ocrheight = coords[3] - coords[1] if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth / 300 height = ocrheight / 300 ocr_dpi = (ocrwidth / width, ocrheight / height) break # there shouldn't be more than one, and if there is, we don't want it if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning print "Warning: DPI unavailable for image %s. Assuming 96 DPI." % ( imageFileName) width = float(im.size[0]) / 96 height = float(im.size[1]) / 96 # create the PDF file pdf = Canvas(outFileName, pagesize=(width * inch, height * inch), pageCompression=1) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page pdf.drawInlineImage(im, 0, 0, width=width * inch, height=height * inch) if self.hocr is not None: for line in self.hocr.findall(".//%sspan" % (self.xmlns)): if line.attrib['class'] == 'ocr_line': coords = self.element_coordinates(line) text = pdf.beginText() text.setFont(fontname, fontsize) text.setTextRenderMode(3) # invisible # set cursor to bottom left corner of line bbox (adjust for dpi) text.setTextOrigin((float(coords[0]) / ocr_dpi[0]) * inch, (height * inch) - (float(coords[3]) / ocr_dpi[1]) * inch) # scale the width of the text to fill the width of the line's bbox text.setHorizScale( (((float(coords[2]) / ocr_dpi[0] * inch) - (float(coords[0]) / ocr_dpi[0] * inch)) / pdf.stringWidth(line.text.rstrip(), fontname, fontsize)) * 100) # write the text to the page text.textLine(line.text.rstrip()) pdf.drawText(text) # finish up the page and save it pdf.showPage() pdf.save()
class PDFInvoice(object): def __init__(self, recipient, invoicedate, duedate, invoicenum=None, imagedir=None, currency='€', preview=False, receipt=False, bankinfo=True): self.pdfdata = StringIO.StringIO() self.canvas = Canvas(self.pdfdata) self.recipient = recipient self.invoicenum = invoicenum self.invoicedate = invoicedate self.duedate = duedate self.imagedir = imagedir or '.' self.currency = currency or '€' self.preview = preview self.receipt = receipt self.bankinfo = bankinfo self.rows = [] if self.receipt: # Never include bank info on receipts self.bankinfo = False self.canvas.setTitle("PostgreSQL Europe Invoice #%s" % self.invoicenum) self.canvas.setSubject("PostgreSQL Europe Invoice #%s" % self.invoicenum) self.canvas.setAuthor("PostgreSQL Europe") self.canvas._doc.info.producer = "PostgreSQL Europe Invoicing System" def addrow(self, title, cost, count=1): self.rows.append((title, cost, count,)) def trimstring(self, s, maxlen, fontname, fontsize): while len(s) > 5: if self.canvas.stringWidth(s, fontname, fontsize) <= maxlen: return s s = s[:len(s)-2] return s def _pageheader(self): if self.preview: t = self.canvas.beginText() t.setTextOrigin(6*cm, 4*cm) t.setFont("Times-Italic", 70) t.setFillColorRGB(0.9,0.9,0.9) t.textLines("PREVIEW PREVIEW") self.canvas.rotate(45) self.canvas.drawText(t) self.canvas.rotate(-45) im = Image("%s/PostgreSQL_logo.1color_blue.300x300.png" % self.imagedir, width=3*cm, height=3*cm) im.drawOn(self.canvas, 2*cm, 25*cm) t = self.canvas.beginText() t.setFillColorRGB(0,0,0,0) t.setFont("Times-Roman", 10) t.setTextOrigin(6*cm, 27.5*cm) t.textLines("""PostgreSQL Europe Carpeaux Diem 13, rue du Square Carpeaux 75018 PARIS France """) self.canvas.drawText(t) t = self.canvas.beginText() t.setTextOrigin(2*cm, 23*cm) t.setFont("Times-Roman", 10) t.textLine("") t.textLines(""" Your contact: Guillaume Lelarge Function: PostgreSQL Europe Treasurer E-mail: [email protected] """) self.canvas.drawText(t) t = self.canvas.beginText() t.setTextOrigin(11*cm, 23*cm) t.setFont("Times-Italic", 11) t.textLine("To:") t.setFont("Times-Roman", 11) t.textLines(self.recipient) self.canvas.drawText(t) p = self.canvas.beginPath() p.moveTo(2*cm, 18.9*cm) p.lineTo(19*cm, 18.9*cm) self.canvas.drawPath(p) def save(self): # We can fit 15 rows on one page. We might want to do something # cute to avoid a single row on it's own page in the future, but # for now, just split it evenly. for pagenum in range(0, (len(self.rows)-1)/15+1): self._pageheader() islastpage = (pagenum == (len(self.rows)-1)/15) if len(self.rows) > 15: suffix = " (page %s/%s)" % (pagenum+1, len(self.rows)/15+1) else: suffix = '' # Center between 2 and 19 is 10.5 if self.invoicenum: if self.receipt: self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT FOR INVOICE NUMBER %s%s" % (self.invoicenum, suffix)) else: self.canvas.drawCentredString(10.5*cm,19*cm, "INVOICE NUMBER %s - %s%s" % (self.invoicenum, self.invoicedate.strftime("%B %d, %Y"),suffix)) else: self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT - %s%s" % (self.invoicedate.strftime("%B %d, %Y"), suffix)) if pagenum == 0: tbldata = [["Item", "Price", "Count", "Amount"], ] else: tbldata = [["Item - continued from page %s" % pagenum, "Price", "count", "amount"], ] tbldata.extend([(self.trimstring(title, 10.5*cm, "Times-Roman", 10), "%.2f %s" % (cost, self.currency), count, "%.2f %s" % ((cost * count), self.currency)) for title,cost, count in self.rows[pagenum*15:(pagenum+1)*15]]) style = [ ('BACKGROUND',(0,0),(3,0),colors.lightgrey), ('ALIGN',(1,0),(3,-1),'RIGHT'), ('LINEBELOW',(0,0),(-1,0), 2, colors.black), ('OUTLINE', (0,0), (-1, -1), 1, colors.black), ] if islastpage: tbldata.append(['','','Total',"%.2f %s" % (sum([cost*count for title,cost,count in self.rows]),self.currency)]) style.append(('LINEABOVE', (-2,-1), (-1, -1), 2, colors.black)) else: tbldata.append([' Continued on page %s' % (pagenum + 2), '', '', '']) style.append(('ALIGN', (0, -1), (-1, -1), 'CENTER')) style.append(('FONT', (0, -1), (-1, -1), 'Times-Italic')) t = Table(tbldata, [10.5*cm, 2.5*cm, 1.5*cm, 2.5*cm]) t.setStyle(TableStyle(style)) w,h = t.wrapOn(self.canvas,10*cm,10*cm) t.drawOn(self.canvas, 2*cm, 18*cm-h) if self.receipt: self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice was paid %s" % self.duedate.strftime("%B %d, %Y")) else: self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice is due: %s" % self.duedate.strftime("%B %d, %Y")) t = self.canvas.beginText() t.setTextOrigin(2*cm, 5*cm) t.setFont("Times-Italic", 10) t.textLine("PostgreSQL Europe is a French non-profit under the French 1901 Law. The association is not VAT registered.") t.textLine("") if islastpage and self.bankinfo: t.setFont("Times-Bold", 10) t.textLine("Bank references / Références bancaires / Bankverbindungen / Referencias bancarias") t.setFont("Times-Roman", 8) t.textLines("""CCM PARIS 1-2 LOUVRE MONTORGUEIL 28 RUE ETIENNE MARCEL 75002 PARIS FRANCE IBAN: FR76 1027 8060 3100 0205 2290 114 BIC: CMCIFR2A """) self.canvas.drawText(t) # Finish this page off, and optionally loop to another one self.canvas.showPage() # Last page is finished, flush the PDF output self.canvas.save() return self.pdfdata
class Invoice: client = Address() provider = Address() items = [] title = "Faktura" vs = "00000000" creator = "" sign_image = None payment_days = 14 paytype = "Převodem" pdffile = None def __init__(self): self.TOP = 260 self.LEFT = 20 pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf')) self.pdffile = NamedTemporaryFile(delete=False) self.pdf = Canvas(self.pdffile.name, pagesize=letter) self.pdf.setFont("DejaVu", 15) self.pdf.setStrokeColorRGB(0, 0, 0) def __del__(self): if os.path.isfile(self.pdffile.name): os.unlink(self.pdffile.name) ############################################################# # Setters ############################################################# def setClient(self, address): self.client = address def setProvider(self, address): self.provider = address def setTitle(self, value): self.title = value def setVS(self, value): self.vs = value def setCreator(self, value): self.creator = value def setPaytype(self, value): self.paytype = value def setPaymentDays(self, value): self.payment_days = int(value) def addItem(self, item): self.items.append(item) ############################################################# # Getters ############################################################# def getContent(self): # Texty self.drawMain() self.drawProvider(self.TOP-10, self.LEFT+3) self.drawClient(self.TOP-30, self.LEFT+91) self.drawPayment(self.TOP-47, self.LEFT+3) self.drawItems(self.TOP-80, self.LEFT) self.drawDates(self.TOP-10, self.LEFT+91) # self.pdf.setFillColorRGB(0, 0, 0) self.pdf.showPage() self.pdf.save() f = open(self.pdffile.name) data = f.read() f.close() os.unlink(self.pdffile.name) return data ############################################################# # Draw methods ############################################################# def drawMain(self): # Horní lajna self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title) self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Variabilní symbol: %s" % self.vs) # Rámečky self.pdf.rect((self.LEFT)*mm, (self.TOP-68)*mm, (self.LEFT+156)*mm, 65*mm, stroke=True, fill=False) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-68)*mm) self.pdf.drawPath(path) path = self.pdf.beginPath() path.moveTo((self.LEFT)*mm, (self.TOP-39)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-39)*mm) self.pdf.drawPath(path) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-23)*mm) path.lineTo((self.LEFT+176)*mm, (self.TOP-23)*mm) self.pdf.drawPath(path) def _drawAddress(self, TOP, LEFT, header_string, address): self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, header_string) self.pdf.setFont("DejaVu", 8) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(address.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm) text.textLines("\n".join(address.getContactLines())) self.pdf.drawText(text) def drawClient(self, TOP, LEFT): self._drawAddress(TOP, LEFT, "Odběratel", self.client) # self.pdf.setFont("DejaVu", 12) # self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel") # self.pdf.setFont("DejaVu", 8) # text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) # text.textLines("\n".join(self.client.getAddressLines())) # self.pdf.drawText(text) # text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) # text.textLines("\n".join(self.client.getContactLines())) # self.pdf.drawText(text) def drawProvider(self, TOP, LEFT): self._drawAddress(TOP, LEFT, "Dodavatel", self.provider) if self.provider.note: self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note) def drawPayment(self, TOP, LEFT): self.pdf.setFont("DejaVu", 11) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Údaje pro platbu") # self.pdf.setFillColorRGB(255, 0, 0) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines( """%s Číslo účtu: %s Variabilní symbol: %s""" % (self.provider.bank_name, self.provider.bank_account, self.vs), ) self.pdf.drawText(text) def drawItems(self, TOP, LEFT): # Items path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-4)*mm) path.lineTo((LEFT+176)*mm, (TOP-4)*mm) self.pdf.drawPath(path) self.pdf.setFont("DejaVu", 9) self.pdf.drawString((LEFT+1)*mm, (TOP-2)*mm, "Fakturuji vám:") i = 9 self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "Množství") self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Cena za jedn.") self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Cena celkem") i += 5 # List total = 0.0 for x in self.items: self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name) i += 5 self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d ks" % x.count) self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "%.2f,- kč" % x.price) self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "%.2f,- kč" % (x.total())) i += 5 total += x.total() path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+176)*mm, (TOP-i)*mm) self.pdf.drawPath(path) self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT+130)*mm, (TOP-i-10)*mm, "Celkem: %d ,- kč" % total) self.pdf.rect((LEFT)*mm, (TOP-i-17)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) # 140,142 if self.sign_image: self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm) path = self.pdf.beginPath() path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm) path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm) self.pdf.drawPath(path) self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Vystavil: %s" % self.creator) def drawDates(self, TOP, LEFT): today = datetime.datetime.today() payback = today+datetime.timedelta(self.payment_days) self.pdf.setFont("DejaVu", 10) self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "Datum vystavení: %s" % today.strftime("%d.%m.%Y")) self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "Datum splatnosti: %s" % payback.strftime("%d.%m.%Y")) self.pdf.drawString((LEFT)*mm, (TOP-9)*mm, "Forma úhrady: " + self.paytype)
def test0(self): "A basic document drawing some strings" # if they do not have the Japanese font files, go away quietly from reportlab.pdfbase.cidfonts import CIDFont, findCMapFile enc = 'ETenms-B5-H' try: findCMapFile(enc) except: #they don't have the font pack, return silently return pdfmetrics.registerFont(CIDFont('MSung-Light',enc)) c = Canvas(outputfile('test_multibyte_cht.pdf')) c.setFont('Helvetica', 24) c.drawString(100,700, 'Traditional Chinese Font Support') c.setFont('Helvetica', 10) c.drawString(100,680, 'Short sample: headline from Yahoo Hong Kong, 20 Oct 2001') c.setFont('MSung-Light-' + enc, 12) # this came from Yahoo Hong Kong leading story today message1 = '\xa5\xac\xae\xed\xbbP\xa6\xbf\xbfA\xa5\xc1\xa6b\xad\xba\xa6\xb8\xb7|\xad\xb1\xab\xe1\xa4@\xa6P\xa8\xa3\xb0O\xaa\xcc\xa1A\xa5L\xbb\xa1\xa1A\xa8\xe2\xa4H\xaa\xba\xad\xba\xa6\xb8\xb7|\xad\xb1\xabD\xb1`' message2 = '\xa6n\xa1A\xa8\xc3\xaa\xed\xa5\xdc\xb2@\xb5L\xba\xc3\xb0\xdd\xa4\xa4\xb0\xea\xa6b\xb3o\xad\xd3\xa5i\xa9\xc6\xaa\xba\xae\xc9\xa8\xe8\xa1A\xb7|\xbbP\xac\xfc\xb0\xea\xa4H\xa5\xc1\xaf\xb8\xa6b\xa4@\xb0_\xa1C' message3 = '\xA7\x41\xA6\x6E\xB6\xDC' c.drawString(100, 655, message1) c.drawString(100, 639, message2) hBoxText(message3 + ' MSung-Light' , c, 100, 600, 'MSung-Light', enc) #hBoxText(message3 + ' MHei-Medium', c, 100, 580, 'MHei-Medium', enc) c.setFont('Helvetica', 10) tx = c.beginText(100, 500) tx.textLines(""" This test document shows Traditional Chinese output from Reportlab PDF Library. You may use one Chinese font, MSung-Light, and a number of different encodings. The available encoding names (with comments from the PDF specification) are: encodings_cht = [ 'B5pc-H', # Macintosh, Big Five character set, Big Five encoding, # Script Manager code 2 'B5pc-V', # Vertical version of B5pc-H 'ETen-B5-H', # Microsoft Code Page 950 (lfCharSet 0x88), Big Five # character set with ETen extensions 'ETen-B5-V', # Vertical version of ETen-B5-H 'ETenms-B5-H', # Microsoft Code Page 950 (lfCharSet 0x88), Big Five # character set with ETen extensions; this uses proportional # forms for half-width Latin characters. 'ETenms-B5-V', # Vertical version of ETenms-B5-H 'CNS-EUC-H', # CNS 11643-1992 character set, EUC-TW encoding 'CNS-EUC-V', # Vertical version of CNS-EUC-H 'UniCNS-UCS2-H', # Unicode (UCS-2) encoding for the Adobe-CNS1 # character collection 'UniCNS-UCS2-V' # Vertical version of UniCNS-UCS2-H. ] The next 32 pages show the complete character set available in the encoding "ETen-B5-H". This is Big5 with the ETen extensions. ETen extensions are the most common extension to Big5 and include circled and roman numbers, Japanese hiragana and katakana, Cyrillic and fractions in rows C6-C8; and 7 extra characters and some line drawing characters in row F9. """) c.drawText(tx) c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() # full Big5 code page c.setFont('Helvetica', 18) c.drawString(72,750, 'Characters available in Big 5') y = 500 for row in range(0xA1,0xFF): cc = Big5CodeChart(row, 'MSung-Light',enc) cc.charsPerRow = 16 cc.rows = 10 cc.codePoints = 160 cc.drawOn(c, 72, y) y = y - cc.height - 25 if y < 50: c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() y = 600 c.save() if VERBOSE: print 'saved '+outputfile('test_multibyte_cht.pdf')
class SimpleInvoice(BaseInvoice): def gen(self, filename): self.TOP = 260 self.LEFT = 20 self.filename = filename pdfmetrics.registerFont(TTFont('DejaVu', FONT_PATH)) pdfmetrics.registerFont(TTFont('DejaVu-Bold', FONT_BOLD_PATH)) self.pdf = Canvas(self.filename, pagesize = letter) self.addMetaInformation(self.pdf) self.pdf.setFont('DejaVu', 15) self.pdf.setStrokeColorRGB(0, 0, 0) # Texty self.drawMain() self.drawTitle() self.drawProvider(self.TOP - 10,self.LEFT + 3) self.drawClient(self.TOP - 35,self.LEFT + 91) self.drawPayment(self.TOP - 47,self.LEFT + 3) self.drawItems(self.TOP - 80,self.LEFT) self.drawDates(self.TOP - 10,self.LEFT + 91) #self.pdf.setFillColorRGB(0, 0, 0) self.pdf.showPage() self.pdf.save() ############################################################# ## Draw methods ############################################################# def addMetaInformation(self, pdf): pdf.setCreator(self.invoice.provider.summary) pdf.setTitle(self.invoice.title) pdf.setAuthor(self.invoice.creator.name) def drawTitle(self): # Up line self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.invoice.title) self.pdf.drawString((self.LEFT + 90) * mm, self.TOP*mm, _(u'Variable symbol: %s') % self.invoice.variable_symbol) def drawMain(self): # Borders self.pdf.rect(self.LEFT * mm, (self.TOP - 68) * mm, (self.LEFT + 156) * mm, 65 * mm, stroke=True, fill=False) path = self.pdf.beginPath() path.moveTo((self.LEFT + 88) * mm, (self.TOP - 3) * mm) path.lineTo((self.LEFT + 88) * mm, (self.TOP - 68) * mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo(self.LEFT * mm, (self.TOP - 39) * mm) path.lineTo((self.LEFT + 88) * mm, (self.TOP - 39) * mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT + 88) * mm, (self.TOP - 27) * mm) path.lineTo((self.LEFT + 176) * mm, (self.TOP - 27) * mm) self.pdf.drawPath(path, True, True) def drawClient(self,TOP,LEFT): self.pdf.setFont('DejaVu', 12) self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Customer')) self.pdf.setFont('DejaVu', 8) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 4) * mm) text.textLines('\n'.join(self.invoice.client.get_address_lines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm) text.textLines('\n'.join(self.invoice.client.get_contact_lines())) self.pdf.drawText(text) if self.invoice.client.note: self.pdf.setFont('DejaVu', 6) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 28) * mm) text.textLines(self.invoice.client.note) self.pdf.drawText(text) def drawProvider(self,TOP,LEFT): self.pdf.setFont('DejaVu', 12) self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Provider')) self.pdf.setFont('DejaVu', 8) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm) text.textLines('\n'.join(self.invoice.provider.get_address_lines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT + 40) * mm, (TOP - 6) * mm) text.textLines('\n'.join(self.invoice.provider.get_contact_lines())) self.pdf.drawText(text) if self.invoice.provider.note: self.pdf.setFont('DejaVu', 6) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm) text.textLines(self.invoice.provider.note) self.pdf.drawText(text) def drawPayment(self,TOP,LEFT): self.pdf.setFont('DejaVu-Bold', 9) self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Payment information')) text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm) lines = [ self.invoice.provider.bank_name, '%s: %s' % (_(u'Bank account'), self.invoice.provider.bank_account), '%s: %s' % (_(u'Variable symbol'), self.invoice.variable_symbol) ] if self.invoice.specific_symbol: lines.append( '%s: %s' % (_(u'Specific symbol'), self.invoice.specific_symbol)) text.textLines('\n'.join(lines)) self.pdf.drawText(text) def drawItems(self,TOP,LEFT): # Items path = self.pdf.beginPath() path.moveTo(LEFT * mm, (TOP - 4) * mm) path.lineTo((LEFT + 176) * mm, (TOP - 4) * mm) self.pdf.drawPath(path, True, True) self.pdf.setFont('DejaVu-Bold', 7) self.pdf.drawString((LEFT + 1) * mm, (TOP - 2) * mm, _(u'List of items')) self.pdf.drawString((LEFT + 1) * mm, (TOP - 9) * mm, _(u'Description')) items_are_with_tax = self.invoice.use_tax if items_are_with_tax: i=9 self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, _(u'Units')) self.pdf.drawString((LEFT + 88) * mm, (TOP - i) * mm, _(u'Price per one')) self.pdf.drawString((LEFT + 115) * mm, (TOP - i) * mm, _(u'Total price')) self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm, _(u'Tax')) self.pdf.drawString((LEFT + 146) * mm, (TOP - i) * mm, _(u'Total price with tax')) i+=5 else: i=9 self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, _(u'Units')) self.pdf.drawString((LEFT + 123) * mm, (TOP - i) * mm, _(u'Price per one')) self.pdf.drawString((LEFT + 150) * mm, (TOP - i) * mm, _(u'Total price')) i+=5 self.pdf.setFont('DejaVu', 7) # List for item in self.invoice.items: self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm, item.description) if item.tax or items_are_with_tax: items_are_with_tax = True if len(item.description) > 52: i+=5 if float(int(item.count)) == item.count: self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%d %s' % (item.count, item.unit)) else: self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%.1f %s' % (item.count, item.unit)) self.pdf.drawString((LEFT + 88) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.price, self.invoice.currency)) self.pdf.drawString((LEFT + 115) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total, self.invoice.currency)) self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm, '%.0f %%' % item.tax) self.pdf.drawString((LEFT + 146) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total_tax, self.invoice.currency)) i+=5 else: if len(item.description) > 75: i+=5 if float(int(item.count)) == item.count: self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, '%d %s' % (item.count, item.unit)) else: self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, '%.1f %s' % (item.count, item.unit)) self.pdf.drawString((LEFT + 123) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.price, self.invoice.currency)) self.pdf.drawString((LEFT + 150) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total, self.invoice.currency)) i+=5 if self.invoice.rounding_result: path = self.pdf.beginPath() path.moveTo(LEFT * mm, (TOP - i) * mm) path.lineTo((LEFT + 176) * mm, (TOP - i) * mm) i += 5 self.pdf.drawPath(path, True, True) self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm, _(u'Rounding')) self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%.2f,- %s' % (self.invoice.difference_in_rounding, self.invoice.currency)) i += 3 path = self.pdf.beginPath() path.moveTo(LEFT * mm, (TOP - i) * mm) path.lineTo((LEFT + 176) * mm, (TOP - i) * mm) self.pdf.drawPath(path, True, True) if not items_are_with_tax: self.pdf.setFont('DejaVu-Bold', 11) self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 7) * mm, _(u'Total')+': %.2f %s' % (self.invoice.price, self.invoice.currency)) else: self.pdf.setFont('DejaVu-Bold', 6) self.pdf.drawString((LEFT + 1) * mm, (TOP - i - 2) * mm, _(u'Breakdown VAT')) vat_list, tax_list, total_list, total_tax_list = [_(u'VAT rate')], [_(u'Tax')], [_(u'Without VAT')], [_(u'With VAT')] for vat, items in self.invoice.generate_breakdown_vat().iteritems(): vat_list.append('%.2f%%' % vat) tax_list.append('%.2f %s' % (items['tax'], self.invoice.currency)) total_list.append('%.2f %s' % (items['total'], self.invoice.currency)) total_tax_list.append('%.2f %s' % (items['total_tax'], self.invoice.currency)) self.pdf.setFont('DejaVu', 6) text = self.pdf.beginText((LEFT + 1) * mm, (TOP - i - 5) * mm) text.textLines('\n'.join(vat_list)) self.pdf.drawText(text) text = self.pdf.beginText((LEFT + 11) * mm, (TOP - i - 5) * mm) text.textLines('\n'.join(tax_list)) self.pdf.drawText(text) text = self.pdf.beginText((LEFT + 27) * mm, (TOP - i - 5) * mm) text.textLines('\n'.join(total_list)) self.pdf.drawText(text) text = self.pdf.beginText((LEFT + 45) * mm, (TOP - i - 5) * mm) text.textLines('\n'.join(total_tax_list)) self.pdf.drawText(text) self.pdf.setFont('DejaVu-Bold', 11) self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 14) * mm, _(u'Total with tax')+': %.2f %s' % (self.invoice.price_tax, self.invoice.currency)) if items_are_with_tax: self.pdf.rect(LEFT * mm, (TOP - i - 17) * mm, (LEFT + 156) * mm, (i + 19) * mm, stroke=True, fill=False) #140,142 else: self.pdf.rect(LEFT * mm, (TOP - i - 11) * mm, (LEFT + 156) * mm, (i + 13) * mm, stroke=True, fill=False) #140,142 if self.invoice.creator.stamp_filename: im = Image.open(self.invoice.creator.stamp_filename) height = float(im.size[1]) / (float(im.size[0])/200.0) self.pdf.drawImage(self.invoice.creator.stamp_filename, (LEFT + 98) * mm, (TOP - i - 72) * mm, 200, height) path = self.pdf.beginPath() path.moveTo((LEFT + 110) * mm, (TOP - i - 70) * mm) path.lineTo((LEFT + 164) * mm, (TOP - i - 70) * mm) self.pdf.drawPath(path, True, True) self.pdf.drawString((LEFT + 112) * mm, (TOP - i - 75) * mm, '%s: %s' % (_(u'Creator'), self.invoice.creator.name)) def drawDates(self,TOP,LEFT): self.pdf.setFont('DejaVu', 10) top = TOP + 1 items = [ (LEFT * mm, '%s: %s' % (_(u'Date'), self.invoice.date)), (LEFT * mm, '%s: %s' % (_(u'Payback'), self.invoice.payback)) ] if self.invoice.taxable_date: items.append((LEFT * mm, '%s: %s' % (_(u'Taxable date'), self.invoice.taxable_date))) items.append((LEFT * mm, '%s: %s' % (_(u'Paytype'), self.invoice.paytype))) for item in items: self.pdf.drawString(item[0], top * mm, item[1]) top += -5
def to_pdf(self, out_filename, image_filename, show_bounding_boxes, hocr_file, dpi, font_name="Helvetica"): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ hocr_tree = etree.ElementTree() hocr_tree.parse(hocr_file) xmlns = self.lookup_namespace(hocr_tree) pt_page_height, pt_page_width = self.calculate_pt_dimensions(dpi, hocr_tree, xmlns) # no width and height definition in the ocr_image element of the hocr file if pt_page_width is None: print ("No page dimension found in the hocr file") sys.exit(1) # Create the PDF file. Page size in points (1/72 in.) pdf = Canvas(out_filename, pagesize=(pt_page_width, pt_page_height), pageCompression=1) # draw bounding box for each paragraph green = Color(0.1, 0.5, 0.1) lime_green = Color(0.8, 1, 0) blue = Color(0, 1, 1) red = Color(1, 0, 0) black = Color(0, 0, 0) word_dict = dict() word_array = dict() paragraph_count = 0 for paragraph_element in hocr_tree.findall(".//%sp[@class='%s']" % (xmlns, "ocr_par")): element_text = self._get_element_text(paragraph_element).rstrip() if len(element_text) == 0: continue paragraph_count += 1 word_array[paragraph_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(paragraph_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, lime_green, blue, is_filled=1, line_width=4) self.annotate_box( pdf, x1, pt_page_height - y1, "p-%d_%s" % (paragraph_count, paragraph_element.get("id").rsplit("_", 1)[1]), ) line_count = 0 for line_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocr_line")): element_text = self._get_element_text(line_element).rstrip() if len(element_text) == 0: continue line_count += 1 word_array[paragraph_count][line_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(line_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, green, blue, is_filled=1, line_width=1) self.annotate_box( pdf, x1, pt_page_height - y2, "l-%d_%s" % (line_count, line_element.get("id").rsplit("_", 1)[1]), right_align=1, ) word_count = 0 for word_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocrx_word")): element_text = self._get_element_text(word_element).rstrip() element_text = self.replace_unsupported_chars(element_text) if len(element_text) == 0: continue word_count += 1 coordinates = self.element_coordinates(word_element) x1, y1, x2, y2 = HocrTransform2.convert_px_coordinates_to_pt(coordinates, dpi) # draw the bbox border if show_bounding_boxes: self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, red, black, line_width=0.5, is_dashed=1) self.annotate_box(pdf, x1, pt_page_height - y1, "w-%d" % word_count, top_align=1) # count_path = 'p(%d)l(%d)w(%d)' % (paragraph_count, line_count, word_count) # id_path = '%s %s %s' % (paragraph_element.get('id'), line_element.get('id'), word_element.get('id')) # print '%s] %s = "%s"' % (count_path, id_path, element_text) # word_dict[word_element.attrib['id']] = self._get_element_text(word_element) # print '%s="%s"' % (word_element.attrib['id'], word_dict[word_element.attrib['id']]) word_array[paragraph_count][line_count][word_count] = { "p": paragraph_count, "l": line_count, "w": word_count, "id": word_element.attrib["id"], "word": element_text, "path": hocr_tree.getpath(word_element), } print word_array[paragraph_count][line_count][word_count] fontsize = self.px2pt(coordinates[3] - coordinates[1], dpi) pdf.setLineWidth(1) pdf.setDash([], 0) pdf.setStrokeColor(black) pdf.setFillColor(black) text = pdf.beginText() text.setTextRenderMode(0) text.setFont(font_name, fontsize) text.setTextOrigin(x1, pt_page_height - y2) text.setHorizScale(100 * (x2 - x1) / pdf.stringWidth(element_text, font_name, fontsize)) text.textLine(element_text) pdf.drawText(text) # print "Word Dict" print word_dict # print "Word Array" # print word_array # pdf.textAnnotation(repr(word_array), name='word_array') # put the image on the page, scaled to fill the page if image_filename is not None: im = Image.open(image_filename) pdf.drawInlineImage(im, 0, 0, width=pt_page_width, height=pt_page_height) # finish up the page and save it pdf.showPage() pdf.save()
def draw(self, invoice, items_page=10): """ Draws the invoice """ buffer = cStringIO.StringIO() invoice_items = invoice['items'] pages = max((len(invoice_items)-2)/items_page+1,1) canvas = Canvas(buffer, pagesize=self.page_size) for page in range(pages): canvas.translate(0, 29.7 * cm) canvas.setFont(self.font_face, 10) canvas.saveState() canvas.setStrokeColorRGB(0.9, 0.5, 0.2) canvas.setFillColorRGB(0.2, 0.2, 0.2) canvas.setFont(self.font_face, 16) canvas.drawString(1 * cm, -1 * cm, invoice.get('title','')) if self.logo: canvas.drawInlineImage(self.logo, 1 * cm, -1 * cm, 250, 16) canvas.setLineWidth(4) canvas.line(0, -1.25 * cm, 21.7 * cm, -1.25 * cm) canvas.restoreState() canvas.saveState() notes = listify(invoice.get('notes','')) textobject = canvas.beginText(1 * cm, -25 * cm) for line in notes: textobject.textLine(line) canvas.drawText(textobject) textobject = canvas.beginText(18 * cm, -28 * cm) textobject.textLine('Pag.%s/%s' % (page+1,pages)) canvas.drawText(textobject) canvas.restoreState() canvas.saveState() business_details = listify(invoice.get('from','FROM:')) canvas.setFont(self.font_face, 9) textobject = canvas.beginText(13 * cm, -2.5 * cm) for line in business_details: textobject.textLine(line) canvas.drawText(textobject) canvas.restoreState() canvas.saveState() client_info = listify(invoice.get('to','TO:')) textobject = canvas.beginText(1.5 * cm, -2.5 * cm) for line in client_info: textobject.textLine(line) canvas.drawText(textobject) canvas.restoreState() textobject = canvas.beginText(1.5 * cm, -6.75 * cm) textobject.textLine(u'Invoice ID: %s' % invoice.get('id','<invoice id>')) textobject.textLine(u'Invoice Date: %s' % invoice.get('date',datetime.date.today())) textobject.textLine(u'Client: %s' % invoice.get('client_name','<invoice client>')) canvas.drawText(textobject) items = invoice_items[1:][page*items_page:(page+1)*items_page] if items: data = [invoice_items[0]] for item in items: data.append([ self.format_currency(x) if isinstance(x,float) else x for x in item]) righta = [k for k,v in enumerate(items[0]) if isinstance(v,(int,float,Decimal))] if page == pages-1: total = self.format_currency(invoice['total']) else: total = '' data.append(['']*(len(items[0])-1)+[total]) colWidths = [2.5*cm]*len(items[0]) colWidths[1] = (21.5-2.5*len(items[0]))*cm table = Table(data, colWidths=colWidths) table.setStyle([ ('FONT', (0, 0), (-1, -1), self.font_face), ('FONTSIZE', (0, 0), (-1, -1), 8), ('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)), ('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)), ('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)), ('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)), ]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta]) tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm) table.drawOn(canvas, 1 * cm, -8 * cm - th) if page == pages-1: items = invoice['totals'][1:] if items: data = [invoice['totals'][0]] for item in items: data.append([ self.format_currency(x) if isinstance(x,float) else x for x in item]) righta = [k for k,v in enumerate(items[0]) if isinstance(v,(int,float,Decimal))] total = self.format_currency(invoice['total']) data.append(['']*(len(items[0])-1)+[total]) colWidths = [2.5*cm]*len(items[0]) colWidths[1] = (21.5-2.5*len(items[0]))*cm table = Table(data, colWidths=colWidths) table.setStyle([ ('FONT', (0, 0), (-1, -1), self.font_face), ('FONTSIZE', (0, 0), (-1, -1), 8), ('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)), ('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)), ('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)), ('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)), ]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta]) tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm) table.drawOn(canvas, 1 * cm, -18 * cm - th) canvas.showPage() canvas.save() return buffer.getvalue()
def to_pdf(self, outFileName, imageFileName=None, showBoundingboxes=False, fontname="Helvetica", invisibleText=False): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ # create the PDF file # page size in points (1/72 in.) pdf = Canvas( outFileName, pagesize=(self.width, self.height), pageCompression=1) # draw bounding box for each paragraph # light blue for bounding box of paragraph pdf.setStrokeColorRGB(0, 1, 1) # light blue for bounding box of paragraph pdf.setFillColorRGB(0, 1, 1) pdf.setLineWidth(0) # no line for bounding box for elem in self.hocr.findall( ".//%sp[@class='%s']" % (self.xmlns, "ocr_par")): elemtxt = self._get_element_text(elem).rstrip() if len(elemtxt) == 0: continue pxl_coords = self.element_coordinates(elem) pt = self.pt_from_pixel(pxl_coords) # draw the bbox border if showBoundingboxes: pdf.rect( pt.x1, self.height - pt.y2, pt.x2 - pt.x1, pt.y2 - pt.y1, fill=1) # check if element with class 'ocrx_word' are available # otherwise use 'ocr_line' as fallback elemclass = "ocr_line" if self.hocr.find( ".//%sspan[@class='ocrx_word']" % (self.xmlns)) is not None: elemclass = "ocrx_word" # itterate all text elements # light green for bounding box of word/line pdf.setStrokeColorRGB(1, 0, 0) pdf.setLineWidth(0.5) # bounding box line width pdf.setDash(6, 3) # bounding box is dashed pdf.setFillColorRGB(0, 0, 0) # text in black for elem in self.hocr.findall( ".//%sspan[@class='%s']" % (self.xmlns, elemclass)): elemtxt = self._get_element_text(elem).rstrip() elemtxt = self.replace_unsupported_chars(elemtxt) if len(elemtxt) == 0: continue pxl_coords = self.element_coordinates(elem) pt = self.pt_from_pixel(pxl_coords) # draw the bbox border if showBoundingboxes: pdf.rect( pt.x1, self.height - pt.y2, pt.x2 - pt.x1, pt.y2 - pt.y1, fill=0) text = pdf.beginText() fontsize = pt.y2 - pt.y1 text.setFont(fontname, fontsize) if invisibleText: text.setTextRenderMode(3) # Invisible (indicates OCR text) # set cursor to bottom left corner of bbox (adjust for dpi) text.setTextOrigin(pt.x1, self.height - pt.y2) # scale the width of the text to fill the width of the bbox text.setHorizScale( 100 * (pt.x2 - pt.x1) / pdf.stringWidth( elemtxt, fontname, fontsize)) # write the text to the page text.textLine(elemtxt) pdf.drawText(text) # put the image on the page, scaled to fill the page if imageFileName is not None: pdf.drawImage(imageFileName, 0, 0, width=self.width, height=self.height) # finish up the page and save it pdf.showPage() pdf.save()
def draw_pdf(buffer, invoice): """ Draws the invoice """ canvas = Canvas(buffer, pagesize=A4) canvas.translate(0, 29.7 * cm) canvas.setFont('Helvetica', 10) canvas.saveState() draw_header(canvas) canvas.restoreState() canvas.saveState() draw_footer(canvas, invoice) canvas.restoreState() canvas.saveState() draw_address(canvas) canvas.restoreState() currency_symbol = invoice.currency.symbol # Client address profile = invoice.to_user.cc3_profile textobject = canvas.beginText(1.5 * cm, -4.5 * cm) textobject.textLine(_(u'Afrekening')) textobject.textLine('') textobject.textLine(profile.business_name) textobject.textLine(_(u"t.a.v. de Crediteurenadministratie")) textobject.textLine(profile.address) textobject.textLine(u"{0} {1}".format(profile.postal_code, profile.city)) textobject.textLine(unicode(profile.country.name)) canvas.drawText(textobject) # Info textobject = canvas.beginText(1.5 * cm, -8.75 * cm) textobject.textLine(_(u'Invoice no: {0}'.format(invoice.inv_no))) textobject.textLine( _(u'Invoice Date: {0}'.format(invoice.inv_date.strftime('%d %b %Y')))) canvas.drawText(textobject) # Items data = [[_(u'Description'), _(u'Total')]] for item in invoice.lines.all(): data.append([ item.description, u"{0:.2f} {1}".format(item.grand_total, currency_symbol), ]) # data.append([u'', _(u'Sub total:') + u" {0:.2f} {1}".format( # invoice.get_sub_total(), currency_symbol)]) # data.append([u'', _(u'Tax:') + u" {0:.2f} {1}".format( # invoice.get_tax(), currency_symbol)]) data.append([ u'', _(u'Total:') + u" {0:.2f} {1}".format(invoice.get_total(), currency_symbol) ]) table = Table(data, colWidths=[14.5 * cm, 4 * cm]) table.setStyle([ ('FONT', (0, 0), (-1, -1), 'Helvetica'), ('FONTSIZE', (0, 0), (-1, -1), 10), ('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)), ('GRID', (0, 0), (-1, -4), 1, (0.7, 0.7, 0.7)), ('GRID', (-2, -3), (-1, -1), 1, (0.7, 0.7, 0.7)), ('ALIGN', (-1, 0), (-1, -1), 'RIGHT'), ('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)), ]) table_widht, table_height, = table.wrapOn(canvas, 15 * cm, 19 * cm) table.drawOn(canvas, 1.5 * cm, -10 * cm - table_height) canvas.showPage() canvas.save()
class Invoice: client = Address() provider = Address() items = [] title = "Faktura" vs = "00000000" creator = "" sign_image = None payment_days = 14 paytype = "Převodem" pdffile = None def __init__(self): self.p = inflect.engine() self.TIN = "23102404783" self.CAN = "20/13/31/2009 21/14/31/2009" self.TOP = 260 self.LEFT = 20 pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf')) self.pdffile = NamedTemporaryFile(delete=False) self.pdf = Canvas(self.pdffile.name, pagesize = letter) self.pdf.setFont("DejaVu", 15) self.pdf.setStrokeColorRGB(0, 0, 0) def __del__(self): if os.path.isfile(self.pdffile.name): os.unlink(self.pdffile.name) ############################################################# ## Setters ############################################################# def setClient(self, address): self.client = address def setProvider(self, address): self.provider = address def setTitle(self, value): self.title = value def setVS(self, value): self.vs = value def setCreator(self, value): self.creator = value def setPaytype(self, value): self.paytype = value def setPaymentDays(self, value): self.payment_days = int(value) def addItem(self, item): self.items.append(item) ############################################################# ## Getters ############################################################# def getContent(self): # Texty self.drawMain() # barcode=code39.Extended39("inv"+str(int(self.vs)),barWidth=0.5*mm,barHeight=5*mm) # barcode.drawOn(self.pdf,self.TOP+45,(self.LEFT+735)) #qrw = QrCodeWidget('hello cruel world!') #self.pdf.add(qrw) # qrw = QrCodeWidget(value = "Invoice" + str(int(self.vs)), barLevel = "Q") # b = qrw.getBounds() # w=b[2]-b[0] # h=b[3]-b[1] # qr_size = 60 # drawing = Drawing(qr_size,qr_size,transform=[float(qr_size)/w,0,0,float(qr_size)/h,0,0]) # drawing.add(qrw) # renderPDF.draw(drawing, self.pdf, self.TOP+25, self.LEFT+710) # qrw.drawOn(self.pdf,self.TOP+45,(self.LEFT+735)) self.drawProvider(self.TOP-8,self.LEFT+3) # self.drawClient(self.TOP-30,self.LEFT+91) self.drawPayment(self.TOP-26,self.LEFT+3) self.drawItems(self.TOP-45,self.LEFT) self.drawDates(self.TOP-10,self.LEFT+91) self.drawWatermark() #self.pdf.setFillColorRGB(0, 0, 0) self.pdf.showPage() self.pdf.save() f = open(self.pdffile.name) data = f.read() f.close() os.unlink(self.pdffile.name) return data ############################################################# ## Draw methods ############################################################# def drawMain(self): # Horní lajna self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title) self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Invoice No.: %s" % self.vs) # Rámečky self.pdf.rect((self.LEFT)*mm, (self.TOP-38)*mm, (self.LEFT+156)*mm, 35*mm, stroke=True, fill=False) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT)*mm, (self.TOP-20)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm) path.lineTo((self.LEFT+176)*mm, (self.TOP-26)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) def drawWatermark(self): pass def drawClient(self,TOP,LEFT): self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel") self.pdf.setFont("DejaVu", 8) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.client.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) text.textLines("\n".join(self.client.getContactLines())) self.pdf.drawText(text) def drawProvider(self,TOP,LEFT): LEFT += 90 self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Address") self.pdf.setFont("DejaVu", 9) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getContactLines())) self.pdf.drawText(text) if self.provider.note: self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note) def drawPayment(self,TOP,LEFT): self.pdf.setFont("DejaVu", 11) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Patient Name") self.pdf.drawString((LEFT+50)*mm, (TOP)*mm, "Date") self.pdf.setFont("DejaVu", 9) text = self.pdf.beginText((LEFT+50)*mm, (TOP-6)*mm) text.textLines(self.date) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.client.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) text.textLines("\n".join(self.client.getContactLines())) self.pdf.drawText(text) self.pdf.drawText(text) def drawItems(self,TOP,LEFT): # Items #path = self.pdf.beginPath() #path.moveTo((LEFT)*mm, (TOP-4)*mm) #path.lineTo((LEFT+176)*mm, (TOP-4)*mm) #self.pdf.drawPath(path, True, True) self.pdf.setFont("DejaVu", 11) i=1 self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, "Description") self.pdf.drawString((LEFT+98)*mm, (TOP-i)*mm, "Quantity") self.pdf.drawString((LEFT+121)*mm, (TOP-i)*mm, "Unit Price") self.pdf.drawString((LEFT+149)*mm, (TOP-i)*mm, "Amount") i+=7 self.pdf.setFont("DejaVu", 9) # List total=0.0 for x in self.items: self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name) i+=0 self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d" % x.count) self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Rs. %.2f" % x.price) self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Rs. %.2f" % (x.total())) i+=5 total += x.total() self.items = [] path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+176)*mm, (TOP-i)*mm) self.pdf.drawPath(path, True, True) total = round(total,2) self.pdf.setFont("DejaVu", 10) self.pdf.drawString((LEFT+1)*mm, (TOP-i-8)*mm, self.p.number_to_words(total).title() + " Rupees Only.") self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT+130)*mm, (TOP-i-8)*mm, "Total: Rs. %s" % total) self.pdf.setFont("Helvetica-Bold", 40) self.pdf.setStrokeGray(0.25) self.pdf.setFillColorRGB(0.95, 0.95, 0.95) self.pdf.drawString((LEFT+60)*mm, (TOP-i)*mm, 'PAID') self.pdf.setFillColorRGB(0, 0, 0) self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142 if self.sign_image: self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm) # if self.creator: # path = self.pdf.beginPath() # path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm) # path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm) # self.pdf.drawPath(path, True, True) # self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Authorized Signatory") def drawDates(self,TOP,LEFT): LEFT -= 90 today = datetime.datetime.today() payback = today+datetime.timedelta(self.payment_days) self.pdf.setFont("DejaVu", 10) self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "TIN: %s" % self.TIN) self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "DL: %s" % self.CAN)
def to_pdf(self, imageFileName, outFileName, fontname="Times-Roman", fontsize=10, withVisibleOCRText=False, withVisibleImage=True, withVisibleBoundingBoxes=False): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ if self.hocr is None: # warn that no text will be embedded in the output PDF print "Warning: No hOCR file specified. PDF will be image-only." im = Image.open(imageFileName) imwidthpx, imheightpx = im.size if 'dpi' in im.info: width = float(im.size[0])/im.info['dpi'][0] height = float(im.size[1])/im.info['dpi'][1] else: # we have to make a reasonable guess # set to None for now and try again using info from hOCR file width = height = None ocr_dpi = (300, 300) # a default, in case we can't find it # get dimensions of the OCR, which may not match the image if self.hocr is not None: for div in self.hocr.findall(".//%sdiv"%(self.xmlns)): if div.attrib['class'] == 'ocr_page': coords = self.element_coordinates(div) ocrwidth = coords[2]-coords[0] ocrheight = coords[3]-coords[1] if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth/300 height = ocrheight/300 ocr_dpi = (ocrwidth/width, ocrheight/height) break # there shouldn't be more than one, and if there is, we don't want it if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning print "Warning: DPI unavailable for image %s. Assuming 96 DPI."%(imageFileName) width = float(im.size[0])/96 height = float(im.size[1])/96 # create the PDF file pdf = Canvas(outFileName, pagesize=(width*inch, height*inch), pageCompression=1) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page if withVisibleImage: pdf.drawInlineImage(im, 0, 0, width=width*inch, height=height*inch) if self.hocr is not None: for word in self.hocr.findall(".//%sspan"%(self.xmlns)): if word.attrib['class'] == 'ocr_word': coords = self.element_coordinates(word) content = self._get_element_text(word) if content.rstrip() == '': continue text = pdf.beginText() text.setFont(fontname, fontsize) if not withVisibleOCRText: #text.setTextRenderMode(0) # visible #else: text.setTextRenderMode(3) # invisible # set cursor to bottom left corner of line bbox (adjust for dpi) # Can't determine original text's baseline, but guess that ypg # roughly push it down by ~2/3 of line height. Correct for that. # PDF y coords increase going *up* the page, remember. Assume "o" is # round so width == line height. origin_y = (height*inch)-(float(coords[3])/ocr_dpi[1])*inch if re.search(r"[gjpqy()]", content): origin_y += pdf.stringWidth("o") * 1/3 if re.search(r"[\[\]()]", content): origin_y += pdf.stringWidth("o") * 1/3.5 elif re.search(r"[,;]", content): origin_y += pdf.stringWidth("o") * 1/4 text.setTextOrigin((float(coords[0])/ocr_dpi[0])*inch, origin_y) # scale the width of the text to fill the width of the line's bbox text.setHorizScale((((float(coords[2])/ocr_dpi[0]*inch)-(float(coords[0])/ocr_dpi[0]*inch))/pdf.stringWidth(content.rstrip(), fontname, fontsize))*100) # write the text to the page text.textLine(content.rstrip()) pdf.drawText(text) # finish up the page and save it pdf.showPage() pdf.save()
class YearlyPdf: client = Address() provider = Address() items = [] title = "Faktura" vs = "00000000" creator = "" sign_image = None payment_days = 14 paytype = "Převodem" pdffile = None def __init__(self): self.p = inflect.engine() #self.TIN = "123121414" #self.CAN = "13123123123" self.TIN = "23102404783" self.CAN = "20/13/31/2009 21/14/31/2009" self.TOP = 260 self.LEFT = 20 pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf')) self.pdffile = NamedTemporaryFile(delete=False) self.pdf = Canvas(self.pdffile.name, pagesize = A4) self.pdf.setFont("DejaVu", 15) self.pdf.setStrokeColorRGB(0, 0, 0) def __del__(self): if os.path.isfile(self.pdffile.name): os.unlink(self.pdffile.name) ############################################################# ## Setters ############################################################# def setClient(self, address): self.client = address def setProvider(self, address): self.provider = address def setTitle(self, value): self.title = value def setVS(self, value): self.vs = value def setCreator(self, value): self.creator = value def setPaytype(self, value): self.paytype = value def setPaymentDays(self, value): self.payment_days = int(value) def addItem(self, item): self.items.append(item) ############################################################# ## Getters ############################################################# def getContent(self): # Texty self.drawMain() self.drawProvider(self.TOP-8,self.LEFT+3) # self.drawClient(self.TOP-30,self.LEFT+91) #self.drawPayment(self.TOP-26,self.LEFT+3) self.pdf.setFont("DejaVu", 18) self.drawDates(self.TOP-10,self.LEFT+91) p = self.drawsItems(self.TOP-35,self.LEFT) #self.pdf.setFillColorRGB(0, 0, 0) self.pdf.showPage() self.pdf.save() f = open(self.pdffile.name) data = f.read() f.close() os.unlink(self.pdffile.name) return data ############################################################# ## Draw methods ############################################################# def drawMain(self): # Horní lajna self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title) self.pdf.drawString((self.LEFT+65)*mm, self.TOP*mm, "Balance Sheet") self.pdf.setFont("DejaVu", 8) self.pdf.drawString((self.LEFT+120)*mm, (self.TOP)*mm, "Dated to: %s" % self.todate) self.pdf.drawString((self.LEFT+120)*mm, (self.TOP+3)*mm, "Dated from: %s" % self.fromdate) # Rámečky #self.pdf.rect((self.LEFT)*mm, (self.TOP-38)*mm, (self.LEFT+156)*mm, 35*mm, stroke=True, fill=False) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT)*mm, (self.TOP-20)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm) path.lineTo((self.LEFT+176)*mm, (self.TOP-26)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm) self.pdf.drawPath(path, True, True) def drawClient(self,TOP,LEFT): self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel") self.pdf.setFont("DejaVu", 8) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.client.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) text.textLines("\n".join(self.client.getContactLines())) self.pdf.drawText(text) def drawProvider(self,TOP,LEFT): LEFT += 90 self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Address") self.pdf.setFont("DejaVu", 9) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getContactLines())) self.pdf.drawText(text) if self.provider.note: self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note) def drawPayment(self,TOP,LEFT): self.pdf.setFont("DejaVu", 11) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Patient Name") self.pdf.drawString((LEFT+50)*mm, (TOP)*mm, "Date") self.pdf.setFont("DejaVu", 9) text = self.pdf.beginText((LEFT+50)*mm, (TOP-6)*mm) text.textLines(self.date) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.client.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) text.textLines("\n".join(self.client.getContactLines())) self.pdf.drawText(text) self.pdf.drawText(text) def drawsItems(self,TOP,LEFT): LEFT += 10 # Items #path = self.pdf.beginPath() #path.moveTo((LEFT)*mm, (TOP-4)*mm) #path.lineTo((LEFT+176)*mm, (TOP-4)*mm) #self.pdf.drawPath(path, True, True) self.pdf.setFont("DejaVu", 11) i=1 self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, "Date") self.pdf.drawString((LEFT+40)*mm, (TOP-i)*mm, "Sale") self.pdf.drawString((LEFT+75)*mm, (TOP-i)*mm, "Purchase") self.pdf.drawString((LEFT+120)*mm, (TOP-i)*mm, "Credit") i+= 2 path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+160)*mm, (TOP-i)*mm) self.pdf.drawPath(path, True, True) i+=7 self.pdf.setFont("DejaVu", 9) # List purchase = 0.0 sale = 0.0 credit = 0.0 for x in self.sitems: if TOP - i < 30: self.pdf.showPage() self.pdf.setFont("DejaVu", 9) i = TOP - 270 self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.date) i+=0 self.pdf.drawString((LEFT+41)*mm, (TOP-i)*mm,"Rs. " + str(x.sale)) self.pdf.drawString((LEFT+76)*mm, (TOP-i)*mm,"Rs. " + str(x.purchase)) self.pdf.drawString((LEFT+121)*mm, (TOP-i)*mm,"Rs. " +str(x.credit)) i+=5 purchase += x.purchase sale += x.sale credit += x.credit path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+160)*mm, (TOP-i)*mm) self.pdf.drawPath(path, True, True) i+= 10 path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+160)*mm, (TOP-i)*mm) self.pdf.drawPath(path, True, True) sale = round(sale,2) purchase = round(purchase,2) credit = round(credit,2) self.pdf.setFont("DejaVu", 10) self.pdf.setFont("DejaVu", 11) self.pdf.drawString((LEFT+2)*mm, (TOP-i+3)*mm, "Total Sale: ") self.pdf.drawString((LEFT+25)*mm, (TOP-i+3)*mm, "Rs. " + str(sale)) self.pdf.drawString((LEFT+52)*mm, (TOP-i+3)*mm, "Purchase: ") self.pdf.drawString((LEFT+73)*mm, (TOP-i+3)*mm, "Rs. " + str(purchase)) self.pdf.drawString((LEFT+97)*mm, (TOP-i+3)*mm, "Credit: ") self.pdf.drawString((LEFT+112)*mm, (TOP-i+3)*mm, "Rs. " + str(credit)) # self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142 if self.sign_image: self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm) return TOP - i # if self.creator: # path = self.pdf.beginPath() # path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm) # path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm) # self.pdf.drawPath(path, True, True) # self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Authorized Signatory") # self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142 def drawDates(self,TOP,LEFT): LEFT -= 90 today = datetime.datetime.today() payback = today+datetime.timedelta(self.payment_days) self.pdf.setFont("DejaVu", 10) self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "TIN: %s" % self.TIN) self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "DL: %s" % self.CAN)
def draw_pdf(buffer, member, details): from members.models import Member """ Draws the invoice """ canvas = Canvas(buffer, pagesize=A4) canvas.translate(0, 29.7 * cm) canvas.setFont('Helvetica', 10) canvas.saveState() draw_header(canvas) canvas.restoreState() canvas.saveState() draw_footer(canvas) canvas.restoreState() canvas.saveState() draw_address(canvas) canvas.restoreState() # member address (aka head-of-list contact details) textobject = canvas.beginText(13 * cm, -3.5 * cm) textobject.textLine(member.head_of_list.first_name + ' ' + unicode.upper(member.head_of_list.last_name)) if member.type == Member.ORG: textobject.textLine(member.organisation.name) textobject.textLine(member.address.street) textobject.textLine(member.address.postal_code + ' ' + member.address.town) textobject.textLine(get_country_from_address(member.address)) canvas.drawText(textobject) # title canvas.setFont('Helvetica', 14) textobject = canvas.beginText(5.5 * cm, -6.75 * cm) textobject.textLine(u'Invoice for the CLUSIL membership for %s' % details['YEAR']) canvas.drawText(textobject) canvas.setFont('Helvetica', 10) # invoice summary textobject = canvas.beginText(1.5 * cm, -8 * cm) textobject.textLine(u'Invoice ID: %s' % details['ID']) textobject.textLine(u'Invoice Date: %s' % details['DATE']) canvas.drawText(textobject) # membership summary textobject = canvas.beginText(1.5 * cm, -9.5 * cm) textobject.textLine(u'Membership type: %s' % Member.MEMBER_TYPES[member.type][1]) if member.type == Member.ORG: textobject.textLine(u'Head-of-list: %s' % details['FULLNAME']) else: textobject.textLine(u'Member: %s' % details['FULLNAME']) if member.type == Member.ORG: textobject.textLine(u'Nb of registered people: %i' % member.lvl) canvas.drawText(textobject) # list of people textobject = canvas.beginText(2.5 * cm, -11 * cm) #head-of-list: textobject.textLine(' - ' + member.head_of_list.first_name + ' ' + unicode.upper(member.head_of_list.last_name)) if member.type == Member.ORG: #delegate: if member.delegate: textobject.textLine(' - ' + member.delegate.first_name + ' ' + unicode.upper(member.delegate.last_name)) for u in member.users.all(): textobject.textLine(' - ' + u.first_name + ' ' + unicode.upper(u.last_name)) canvas.drawText(textobject) offset = member.users.count() / 3 # fee textobject = canvas.beginText(2.5 * cm, -(14+offset) * cm) textobject.textLine(u'Total amount of the CLUSIL membership fee: %s' % unicode(details['AMOUNT']) + u' EUR') canvas.drawText(textobject) # thank you message textobject = canvas.beginText(1.5 * cm, -(16+offset) * cm) textobject.textLine(u'Thank you for being a CLUSIL member.') textobject.textLine(u'Please be so kind and pay the membership fee within the next two weeks.') canvas.drawText(textobject) canvas.showPage() canvas.save()
class Invoice: client = Address() provider = Address() items = [] title = "Faktura" vs = "00000000" creator = "" sign_image = None payment_days = 14 paytype = "Převodem" pdffile = None def __init__(self): self.TOP = 260 self.LEFT = 20 pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf')) self.pdffile = NamedTemporaryFile(delete=False) self.pdf = Canvas(self.pdffile.name, pagesize = letter) self.pdf.setFont("DejaVu", 15) self.pdf.setStrokeColorRGB(0, 0, 0) def __del__(self): if os.path.isfile(self.pdffile.name): os.unlink(self.pdffile.name) ############################################################# ## Setters ############################################################# def setClient(self, address): self.client = address def setProvider(self, address): self.provider = address def setTitle(self, value): self.title = value def setVS(self, value): self.vs = value def setCreator(self, value): self.creator = value def setPaytype(self, value): self.paytype = value def setPaymentDays(self, value): self.payment_days = int(value) def addItem(self, item): self.items.append(item) ############################################################# ## Getters ############################################################# def getContent(self): # Texty self.drawMain() self.drawProvider(self.TOP-10,self.LEFT+3) self.drawClient(self.TOP-30,self.LEFT+91) self.drawPayment(self.TOP-47,self.LEFT+3) self.drawItems(self.TOP-80,self.LEFT) self.drawDates(self.TOP-10,self.LEFT+91) #self.pdf.setFillColorRGB(0, 0, 0) self.pdf.showPage() self.pdf.save() f = open(self.pdffile.name) data = f.read() f.close() os.unlink(self.pdffile.name) return data ############################################################# ## Draw methods ############################################################# def drawMain(self): # Horní lajna self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title) self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Variabilní symbol: %s" % self.vs) # Rámečky self.pdf.rect((self.LEFT)*mm, (self.TOP-68)*mm, (self.LEFT+156)*mm, 65*mm, stroke=True, fill=False) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-68)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT)*mm, (self.TOP-39)*mm) path.lineTo((self.LEFT+88)*mm, (self.TOP-39)*mm) self.pdf.drawPath(path, True, True) path = self.pdf.beginPath() path.moveTo((self.LEFT+88)*mm, (self.TOP-23)*mm) path.lineTo((self.LEFT+176)*mm, (self.TOP-23)*mm) self.pdf.drawPath(path, True, True) def drawClient(self,TOP,LEFT): self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel") self.pdf.setFont("DejaVu", 8) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.client.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm) text.textLines("\n".join(self.client.getContactLines())) self.pdf.drawText(text) def drawProvider(self,TOP,LEFT): self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Dodavatel") self.pdf.setFont("DejaVu", 8) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getAddressLines())) self.pdf.drawText(text) text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm) text.textLines("\n".join(self.provider.getContactLines())) self.pdf.drawText(text) if self.provider.note: self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note) def drawPayment(self,TOP,LEFT): self.pdf.setFont("DejaVu", 11) self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Údaje pro platbu") #self.pdf.setFillColorRGB(255, 0, 0) text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm) text.textLines("""%s Číslo účtu: %s Variabilní symbol: %s"""%(self.provider.bank_name ,self.provider.bank_account, self.vs)) self.pdf.drawText(text) def drawItems(self,TOP,LEFT): # Items path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-4)*mm) path.lineTo((LEFT+176)*mm, (TOP-4)*mm) self.pdf.drawPath(path, True, True) self.pdf.setFont("DejaVu", 9) self.pdf.drawString((LEFT+1)*mm, (TOP-2)*mm, "Fakturuji vám:") i=9 self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "Množství") self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Cena za jedn.") self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Cena celkem") i+=5 # List total=0.0 for x in self.items: self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name) i+=5 self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d ks" % x.count) self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "%.2f,- kč" % x.price) self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "%.2f,- kč" % (x.total())) i+=5 total += x.total() path = self.pdf.beginPath() path.moveTo((LEFT)*mm, (TOP-i)*mm) path.lineTo((LEFT+176)*mm, (TOP-i)*mm) self.pdf.drawPath(path, True, True) self.pdf.setFont("DejaVu", 12) self.pdf.drawString((LEFT+130)*mm, (TOP-i-10)*mm, "Celkem: %d ,- kč" % total) self.pdf.rect((LEFT)*mm, (TOP-i-17)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142 if self.sign_image: self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm) path = self.pdf.beginPath() path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm) path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm) self.pdf.drawPath(path, True, True) self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Vystavil: %s" % self.creator) def drawDates(self,TOP,LEFT): today = datetime.datetime.today() payback = today+datetime.timedelta(self.payment_days) self.pdf.setFont("DejaVu", 10) self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "Datum vystavení: %s" % today.strftime("%d.%m.%Y")) self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "Datum splatnosti: %s" % payback.strftime("%d.%m.%Y")) self.pdf.drawString((LEFT)*mm, (TOP-9)*mm, "Forma úhrady: " + self.paytype)
def test0(self): "A basic document drawing some strings" c = Canvas(outputfile('test_multibyte_jpn.pdf')) c.setFont('Helvetica', 30) c.drawString(100, 700, 'Japanese Font Support') c.setStrokeColor(colors.red) #unicode font automatically supplies the encoding pdfmetrics.registerFont(UnicodeCIDFont('HeiseiMin-W3')) msg = u'\u6771\u4EAC : Unicode font, unicode input' self.hDraw(c, msg, 'HeiseiMin-W3', 100, 600) msg = u'\u6771\u4EAC : Unicode font, utf8 input'.encode('utf8') self.hDraw(c, msg, 'HeiseiMin-W3', 100, 575) # now try verticals - this is broken, not sure how to make it # work in post Unicode world. pdfmetrics.registerFont(CIDFont('HeiseiMin-W3', '90ms-RKSJ-V')) c.setFont('HeiseiMin-W3-90ms-RKSJ-V', 16) c.drawString(450, 650, '\223\214\213\236 vertical Shift-JIS') height = c.stringWidth('\223\214\213\236 vertical Shift-JIS', 'HeiseiMin-W3-90ms-RKSJ-V', 16) c.rect(450 - 8, 650, 16, -height) pdfmetrics.registerFont(CIDFont('HeiseiMin-W3', 'EUC-V')) c.setFont('HeiseiMin-W3-EUC-V', 16) c.drawString(475, 650, '\xC5\xEC\xB5\xFE vertical EUC') height = c.stringWidth('\xC5\xEC\xB5\xFE vertical EUC', 'HeiseiMin-W3-EUC-V', 16) c.rect(475 - 8, 650, 16, -height) from reportlab.platypus.paragraph import Paragraph from reportlab.lib.styles import ParagraphStyle jStyle = ParagraphStyle('jtext', fontName='HeiseiMin-W3', fontSize=12, wordWrap="CJK") gatwickText = '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99\xe3\x81\x97\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' gatwickText2 = '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf<font color=red>\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90</font>\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88<link fg="blue" href="http://www.reportlab.com">\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99</link>\xe3\x81\x97\xe3\x81\xa6<u>\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99</u>\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' c.setFont('HeiseiMin-W3', 12) jPara = Paragraph(gatwickText, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 220) jPara = Paragraph(gatwickText2, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 320) c.setFillColor(colors.purple) tx = c.beginText(100, 200) tx.setFont('Helvetica', 12) tx.textLines("""This document shows sample output in Japanese from the Reportlab PDF library. This page shows the two fonts available and tests our ability to measure the width of glyphs in both horizontal and vertical writing, with proportional and fixed-width characters. The red boxes should be the same width (or height) as the character strings they surround. The next pages show more samples and information. """) c.drawText(tx) c.setFont('Helvetica', 10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() c.setFont('Helvetica', 30) c.drawString(100, 700, 'Japanese TrueType Font Support') msg = u'\u6771\u4EAC : Unicode font'.encode('utf8') msg2 = u'utf8 input 0123456789 ABCDEF'.encode('utf8') from reportlab.pdfbase.ttfonts import TTFont try: msmincho = TTFont('MS Mincho', 'msmincho.ttc', subfontIndex=0, asciiReadable=0) fn = ' file=msmincho.ttc subfont 0' except: try: msmincho = TTFont('MS Mincho', 'msmincho.ttf', asciiReadable=0) fn = 'file=msmincho.ttf' except: #Ubuntu - works on Lucid Lynx if xpdf-japanese installed try: msmincho = TTFont('MS Mincho', 'ttf-japanese-mincho.ttf') fn = 'file=msmincho.ttf' except: msmincho = None if msmincho is None: c.setFont('Helvetica', 12) c.drawString(100, 600, 'Cannot find msmincho.ttf or msmincho.ttc') else: pdfmetrics.registerFont(msmincho) c.setFont('MS Mincho', 30) c.drawString(100, 600, msg) c.drawString(100, 570, msg2) c.drawString(100, 540, fn) if fn.endswith('0'): try: msmincho1 = TTFont('MS Mincho 1', 'msmincho.ttc', subfontIndex=1, asciiPreload=0) pdfmetrics.registerFont(msmincho1) fn = ' file=msmincho.ttc subfont 1' c.setFont('MS Mincho 1', 30) c.drawString(100, 500, msg + fn) except: c.setFont('Helvetica', 30) c.drawString(100, 500, msg) c.drawString(100, 470, msg2) c.drawString(100, 440, fn) #test a paragraph with CJK and <br/> tags u = u'''<font color=red>\u30ac\u30c8\u30a6\u30a3\u30c3</font><br/><font color=blue>\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a</font><br/>\u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f<br/>\u4e00\u306e\u30db\u30c6\u30eb\u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b\u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4\u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8<br/>\u74b0\u5883\u3092\u5b8c\u5099\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0\u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a\u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8\u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054\u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4\u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599\u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' jPara = Paragraph(u, jStyle) jPara.wrap(300, 500) jPara.drawOn(c, 100, 300) c.showPage() # realistic text sample ## sample = """Adobe Acrobat ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xaa\x8aJ\x82\xa9\x82\xc8\x82\xad\x82\xc4\x8d\xa2\x82\xc1\x82\xbd\x82\xb1\x82\xc6\x82\xcd ##\x82\xa0\x82\xe8\x82\xdc\x82\xb9\x82\xf1\x82\xa9\x81B\x8e\x96\x8b\xc6\x8cv\x89\xe6\x8f\x91\x81A\x89c\x8b\xc6\x83\x8c\x83|\x81[\x83g ##\x81A\x83J\x83^\x83\x8d\x83O\x82\xe2\x83p\x83\x93\x83t\x83\x8c\x83b\x83g\x82\xc8\x82\xc7\x90\xa7\x8d\xec\x95\xa8\x82\xcc\x8e\xed ##\x97\xde\x82\xc9\x82\xa9\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xcdAdobe® Acrobat® 5.0\x82\xf0\x8eg\x82\xc1\x82\xc4Adobe PDF\x81iPortable Document ##Format\x81j\x83t\x83@\x83C\x83\x8b\x82\xc9\x95\xcf\x8a\xb7\x82\xb5\x82\xdc\x82\xb5\x82\xe5\x82\xa4\x81B\x96\xb3\x8f\x9e\x94z\x95z\x82\xcc ##Adobe Acrobat Reader\x82\xf0\x8eg\x82\xa6\x82\xce\x81A\x83n\x81[\x83h\x83E\x83F\x83A\x81A\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc9\x82\xa9 ##\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A\x92N\x82\xc5\x82\xe0\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xf0 ##\x83I\x83\x8a\x83W\x83i\x83\x8b\x82\xcc\x91\xcc\x8d\xd9\x82\xc5\x8aJ\x82\xad\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x88\xd3\x90}\x82\xb5\x82\xbd\x82\xc6\x82\xa8\x82\xe8\x82\xc9\x8f\xee\x95\xf1\x82\xf0\x93`\x82\xa6\x82\xe9 ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xb3\x82\xe7\x82\xc9\x81AAdobe Acrobat 5.0\x82\xc5\x82\xcd\x81AWeb\x83u\x83\x89\x83E\x83U\x82\xa9\x82\xe7\x83R\x83\x81\x83\x93\x83g\x82\xe2 ##\x83}\x81[\x83N\x83A\x83b\x83v\x82\xf0\x8f\x91\x82\xab\x8d\x9e\x82\xf1\x82\xbe\x82\xe8\x81A\x93d\x8eq\x8f\x90\x96\xbc\x82\xf0\x8f\x91\x82\xab ##\x8d\x9e\x82\xdd\x81A\x8c\xb4\x96{\x82\xc6\x82\xb5\x82\xc4\x83\x8d\x81[\x83J\x83\x8b\x82\xc9\x95\xdb\x91\xb6\x82\xb7\x82\xe9\x82\xb1\x82\xc6\x82\xe0\x89\xc2\x94\\\x82\xc5\x82\xb7\x81B ##\x8a\xe9\x8b\xc6\x93\xe0\x82\xa0\x82\xe9\x82\xa2\x82\xcd\x8a\xe9\x8b\xc6\x82\xcc\x98g\x82\xf0\x92\xb4\x82\xa6\x82\xc4\x83`\x81[\x83\x80\x82\xc5 ##\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x83\x8f\x81[\x83N\x82\xcc\x90\xb6\x8eY\x90\xab\x82\xf0\x8c\xfc\x8f\xe3\x82\xb3\x82\xb9\x82\xe9\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ## ##Adobe Acrobat 5.0\x82\xc5\x8d\xec\x90\xac\x82\xb5\x82\xbdAdobe PDF\x82\xcd\x81A(Acrobat 5.0\x82\xc5\x82\xcc\x82\xdd\x83T\x83|\x81[\x83g ##\x82\xb5\x82\xc4\x82\xa2\x82\xe9\x88\xc3\x8d\x86\x89\xbb\x90\xdd\x92\xe8\x82\xf0\x8f\x9c\x82\xa2\x82\xc4\x82\xcd)\x8f]\x97\x88\x82\xdc ##\x82\xc5\x82\xcc\x83o\x81[\x83W\x83\x87\x83\x93(3\x82\xa8\x82\xe6\x82\xd1\x82S)\x82\xccAcrobat Reader\x82\xc5\x82\xe0\x8aJ\x82\xad ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B\x8f\xee\x95\xf1\x8b\xa4\x97L\x82\xcc\x83c\x81[\x83\x8b\x82\xc6\x82\xb5 ##\x82\xc4\x81A\x82\xb3\x82\xe7\x82\xc9\x90i\x95\xe0\x82\xb5\x82\xbdAdobe Acrobat 5.0\x82\xf0\x81A\x8f]\x97\x88\x82\xcc\x8a\xc2\x8b\xab ##\x82\xc5\x82\xe0\x88\xc0\x90S\x82\xb5\x82\xc4\x82\xb2\x97\x98\x97p\x82\xa2\x82\xbd\x82\xbe\x82\xaf\x82\xdc\x82\xb7\x81B ## ##\x96{\x90\xbb\x95i\x82\xf0\x83l\x83b\x83g\x83\x8f\x81[\x83N\x82\xc8\x82\xc7\x82\xf0\x89\xee\x82\xb5\x82\xc4\x92\xbc\x90\xda\x82\xa0\x82\xe9 ##\x82\xa2\x82\xcd\x8a\xd4\x90\xda\x82\xc9\x95\xa1\x90\x94\x82\xcc\x92[\x96\x96\x82\xa9\x82\xe7\x8eg\x97p\x82\xb7\x82\xe9\x8f\xea\x8d\x87\x81A ##\x82\xbb\x82\xcc\x92[\x96\x96\x82\xc6\x93\xaf\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xad\x82\xbe ##\x82\xb3\x82\xa2\x81B\x96{\x90\xbb\x95i\x82\xcd\x83N\x83\x89\x83C\x83A\x83\x93\x83g\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc5\x82\xa0\x82\xe8 ##\x81A\x83T\x81[\x83o\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc6\x82\xb5\x82\xc4\x82\xa8\x8eg\x82\xa2\x82\xa2\x82\xbd\x82\xbe\x82\xad\x82\xb1\x82\xc6 ##\x82\xcd\x81A\x8f\xe3\x8bL\x95\xfb\x96@\x82\xc9\x82\xe6\x82\xe9\x88\xc8\x8aO\x81A\x8b\x96\x91\xf8\x82\xb3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb9 ##\x82\xf1\x81B\x95\xa1\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xb3\x82\xea\x82\xe9\x8f\xea\x8d\x87\x82\xc9 ##\x82\xcd\x83\x89\x83C\x83Z\x83\x93\x83X\x83v\x83\x8d\x83O\x83\x89\x83\x80\x82\xf0\x82\xb2\x97\x98\x97p\x82\xc9\x82\xc8\x82\xe9\x82\xc6\x82\xa8\x93\xbe\x82\xc5\x82\xb7\x81B ## ## ##\x81y\x82\xa8\x92m\x82\xe7\x82\xb9\x81zMicrosoft Office XP\x82\xa9\x82\xe7PDF\x82\xf0\x8d\xec\x90\xac\x82\xb7\x82\xe9\x82\xc9\x82\xcd ##""" ## c.setFont('Helvetica', 24) ## c.drawString(100,750, "Sample text from Adobe's web site") ## tx = c.beginText(100,700) ## tx.setFont('Helvetica', 10) ## tx.textLine('Note: line wrapping has not been preserved and some lines may be wrapped in mid-word.') ## tx.textLine('We are just testing that we see Japanese and not random characters!') ## tx.setFont('HeiseiMin-W3-90ms-RKSJ-H',6) ## tx.textLines(sample) ## tx.setFont('Helvetica', 8) ## tx.textLine() ## tx.textLine() ## tx.textLines(""" ## This test document shows Japanese output from the Reportlab PDF Library. ## You may use two fonts, HeiseiMin-W3 and HeiseiKakuGo-W5, and a number of ## different encodings. ## ## The available encoding names (with comments from the PDF specification) are: ## encodings_jpn = [ ## # official encoding names, comments taken verbatim from PDF Spec ## '83pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk6 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## '90ms-RKSJ-H', #Microsoft Code Page 932 (lfCharSet 0x80), JIS X 0208 ## #character set with NEC and IBM extensions ## '90ms-RKSJ-V', #Vertical version of 90ms-RKSJ-H ## '90msp-RKSJ-H', #Same as 90ms-RKSJ-H, but replaces half-width Latin ## #characters with proportional forms ## '90msp-RKSJ-V', #Vertical version of 90msp-RKSJ-H ## '90pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk7 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## 'Add-RKSJ-H', #JIS X 0208 character set with Fujitsu FMR extensions, ## #Shift-JIS encoding ## 'Add-RKSJ-V', #Vertical version of Add-RKSJ-H ## 'EUC-H', #JIS X 0208 character set, EUC-JP encoding ## 'EUC-V', #Vertical version of EUC-H ## 'Ext-RKSJ-H', #JIS C 6226 (JIS78) character set with NEC extensions, ## #Shift-JIS encoding ## 'Ext-RKSJ-V', #Vertical version of Ext-RKSJ-H ## 'H', #JIS X 0208 character set, ISO-2022-JP encoding, ## 'V', #Vertical version of H ## 'UniJIS-UCS2-H', #Unicode (UCS-2) encoding for the Adobe-Japan1 character ## #collection ## 'UniJIS-UCS2-V', #Vertical version of UniJIS-UCS2-H ## 'UniJIS-UCS2-HW-H', #Same as UniJIS-UCS2-H, but replaces proportional Latin ## #characters with half-width forms ## 'UniJIS-UCS2-HW-V' #Vertical version of UniJIS-UCS2-HW-H ## ] ## ## The next few pages show the complete character set available in the encoding ## "90ms-RKSJ-H" - Shift-JIS with the standard Microsoft extensions. ## """) ## c.drawText(tx) ## ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## ## ## ## c.showPage() from reportlab.lib import textsplit c.setFont('HeiseiMin-W3', 14) y = 700 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_START_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica', 10) c.drawString(70, y, ' '.join(map(lambda x: repr(x)[4:-1], group))) c.setFont('HeiseiMin-W3', 14) y -= 20 y -= 20 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_END_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica', 10) c.drawString(70, y, ' '.join(map(lambda x: repr(x)[2:], group))) c.setFont('HeiseiMin-W3', 14) y -= 20 c.showPage() #utf8 encoded paragraph sample2_uni = u'''\u30ac\u30c8\u30a6\u30a3\u30c3\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a \u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f\u4e00\u306e\u30db\u30c6\u30eb \u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b \u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4 \u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u74b0\u5883\u3092\u5b8c\u5099 \u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0 \u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002 \u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a \u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8 \u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054 \u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4 \u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599 \u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' oneline_uni = u''.join(sample2_uni.split()) sample2_utf8 = oneline_uni.encode('utf8') from reportlab.platypus import Paragraph from reportlab.lib.styles import ParagraphStyle jsty = ParagraphStyle('japanese', fontName='HeiseiMin-W3', wordWrap='CJK') jpara = Paragraph(oneline_uni, style=jsty) c.drawString( 100, 710, 'Try to wrap a paragraph using a style with wordWrap="CJK"') w, h = jpara.wrap(400, 400) jpara.drawOn(c, 100, 700 - h) #now try to split it... c.drawString(100, 510, 'Now try to split a paragraph as if over a page break') topPara, bottomPara = jpara.split(400, 30) w1, h1 = topPara.wrap(400, 30) topPara.drawOn(c, 100, 450) w2, h2 = bottomPara.wrap(400, 30) bottomPara.drawOn(c, 100, 400) #print 'split into heights %0.2f, %0.2f' % (topPara.height, bottomPara.height) ## c.showPage() ## ## ## # full kuten chart in EUC ## c.setFont('Helvetica', 24) ## c.drawString(72,750, 'Characters available in JIS 0208-1997') ## y = 600 ## for row in range(1, 95): ## KutenRowCodeChart(row, 'HeiseiMin-W3','EUC-H').drawOn(c, 72, y) ## y = y - 125 ## if y < 50: ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## c.showPage() ## y = 700 ## ## c.showPage() #try with Unicode truetype - Mincho for starters ## import time ## started = time.clock() ## c.showPage() ## c.setFont('Helvetica',16) ## c.drawString(100,750, 'About to say Tokyo in MS Gothic...') ## ## from reportlab.pdfbase.ttfonts import TTFont, TTFontFile ## f = TTFontFile("msgothic.ttf") ## print f.name ## ## pdfmetrics.registerFont(TTFont(f.name, f)) ## ## utfText = u'Andr\202'.encode('utf8') ## c.setFont(f.name,16) ## c.drawString(100,700, utfText) ## ## ## #tokyoUCS2 = '\x67\x71\x4E\xAC' ## finished = time.clock() c.save() if VERBOSE: print 'saved test_multibyte_jpn.pdf'
class InvoiceTemplate(object): def __init__(self, filename, logo_filename=LOGO_FILENAME, from_address=Address(**settings.INVOICE_FROM_ADDRESS), to_address=None, project_name='', invoice_date=None, invoice_number='', terms=settings.INVOICE_TERMS, due_date=None, date_start=None, date_end=None, bank_name=settings.BANK_NAME, bank_address=Address(**settings.BANK_ADDRESS), account_number=settings.BANK_ACCOUNT_NUMBER, routing_number_ach=settings.BANK_ROUTING_NUMBER_ACH, routing_number_wire=settings.BANK_ROUTING_NUMBER_WIRE, swift_code=settings.BANK_SWIFT_CODE, applied_credit=None, subtotal=None, tax_rate=None, applied_tax=None, total=None, is_wire=False, is_prepayment=False): self.canvas = Canvas(filename) self.canvas.setFontSize(DEFAULT_FONT_SIZE) self.logo_filename = os.path.join(os.getcwd(), logo_filename) self.from_address = from_address self.to_address = to_address self.project_name = project_name self.invoice_date = invoice_date self.invoice_number = invoice_number self.terms = terms self.due_date = due_date self.date_start = date_start self.date_end = date_end self.bank_name = bank_name self.bank_address = bank_address self.account_number = account_number self.routing_number_ach = routing_number_ach self.routing_number_wire = routing_number_wire self.swift_code = swift_code self.applied_credit = applied_credit self.subtotal = subtotal self.tax_rate = tax_rate self.applied_tax = applied_tax self.total = total self.is_wire = is_wire self.is_prepayment = is_prepayment self.items = [] def add_item(self, description, quantity, unit_cost, subtotal, credits, total): self.items.append(PdfLineItem(description, quantity, unit_cost, subtotal, credits, total)) def get_pdf(self): self.draw_logo() self.draw_from_address() self.draw_to_address() self.draw_project_name() if not self.is_prepayment: self.draw_statement_period() self.draw_invoice_label() self.draw_details() if not self.is_wire or self.is_prepayment: self.draw_table() self.draw_footer() self.canvas.showPage() self.canvas.save() def draw_logo(self): self.canvas.drawImage(self.logo_filename, inches(0.5), inches(2.5), width=inches(1.5), preserveAspectRatio=True) def draw_text(self, string, x, y): text = self.canvas.beginText() text.setTextOrigin(x, y) for line in string.split('\n'): text.textLine(line) self.canvas.drawText(text) def draw_from_address(self): if self.from_address is not None: self.draw_text(unicode(self.from_address), inches(3), inches(11)) def draw_to_address(self): origin_x = inches(1) origin_y = inches(9.2) self.canvas.translate(origin_x, origin_y) left = inches(0) right = inches(4.5) top = inches(0.3) middle_horizational = inches(0) bottom = inches(-1.7) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, middle_horizational, right - left, top - middle_horizational, fill=1) self.canvas.setFillColorRGB(*BLACK) self.draw_text("Bill To", left + inches(0.2), middle_horizational + inches(0.1)) if self.to_address is not None: self.draw_text(unicode(self.to_address), inches(0.1), inches(-0.2)) self.canvas.translate(-origin_x, -origin_y) def draw_project_name(self): origin_x = inches(1) origin_y = inches(7.4) self.canvas.translate(origin_x, origin_y) left = inches(0) middle_vertical = inches(1) right = inches(4.5) top = inches(0) bottom = inches(-0.3) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, bottom, middle_vertical - left, top - bottom, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawCentredString(midpoint(left, middle_vertical), bottom + inches(0.1), "Project") self.canvas.drawString(middle_vertical + inches(0.2), bottom + inches(0.1), self.project_name) self.canvas.translate(-origin_x, -origin_y) def draw_statement_period(self): origin_x = inches(1) origin_y = inches(6.75) self.canvas.translate(origin_x, origin_y) self.canvas.drawString( 0, 0, "Statement period from %s to %s" % (self.date_start.strftime(USER_DATE_FORMAT) if self.date_start is not None else "", self.date_end.strftime(USER_DATE_FORMAT) if self.date_end is not None else "")) self.canvas.translate(-origin_x, -origin_y) def draw_invoice_label(self): self.canvas.setFontSize(size=24) self.canvas.drawString(inches(6.5), inches(10.8), "Invoice") self.canvas.setFontSize(DEFAULT_FONT_SIZE) def draw_details(self): origin_x = inches(5.75) origin_y = inches(9.5) self.canvas.translate(origin_x, origin_y) left = inches(0) right = inches(2) bottom = inches(0) top = inches(1.25) label_height = (top - bottom) / 6.0 label_offset = label_height * 0.8 content_offset = 1.5 * label_offset middle_x = midpoint(left, right) middle_y = midpoint(bottom, top) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, middle_y - label_height, right - left, label_height, fill=1) self.canvas.rect(left, top - label_height, right - left, label_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.rect(left, bottom, 0.5 * (right - left), top - bottom) self.canvas.rect(left, bottom, right - left, 0.5 * (top - bottom)) self.canvas.drawCentredString(midpoint(left, middle_x), top - label_offset, "Date") self.canvas.drawCentredString(midpoint(left, middle_x), top - label_height - content_offset, str(self.invoice_date)) self.canvas.drawCentredString(midpoint(middle_x, right), top - label_offset, "Invoice #") self.canvas.drawCentredString(midpoint(middle_x, right), top - label_height - content_offset, self.invoice_number) self.canvas.drawCentredString(midpoint(left, middle_x), middle_y - label_offset, "Terms") self.canvas.drawCentredString(midpoint(left, middle_x), middle_y - label_height - content_offset, self.terms) self.canvas.drawCentredString(midpoint(middle_x, right), middle_y - label_offset, "Due Date") self.canvas.drawCentredString(midpoint(middle_x, right), middle_y - label_height - content_offset, str(self.due_date)) self.canvas.translate(-origin_x, -origin_y) def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(2.9) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.3) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Product") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Unit Cost") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits Applied") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y) def draw_footer(self): from corehq.apps.domain.views import DomainBillingStatementsView self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.65), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(3.05), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.75), "Tax (%0.2f%%):" % self.tax_rate) self.canvas.drawString(inches(5.6), inches(2.45), "Credit:") self.canvas.drawString(inches(5.2), inches(1.85), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(3.05), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.75), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(1.4), "Thank you for using CommCare HQ.") payment_description = ( "Payment Options:<br />" "<strong>Credit card payments</strong> are preferred and can be made online here: " "<link href='%(payment_page)s' color='blue'>%(payment_page)s</link><br />" "<br />" "<strong>ACH or Wire:</strong> If you make payment via ACH or Wire, please make sure to email " "<font color='blue'>%(invoicing_contact_email)s</font> " "so that we can match your payment to the correct invoice. Please include: " "Invoice #, Project Space, and payment date in the email. <br />" ) % { 'invoicing_contact_email': settings.INVOICING_CONTACT_EMAIL, 'payment_page': absolute_reverse(DomainBillingStatementsView.urlname, args=[self.project_name]), } payment_info = Paragraph(payment_description, ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.5), inches(1.8)) ach_payment_text = ( "<strong>ACH payment</strong> (preferred over wire payment for transfer in the US):<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_ach)s<br />" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_ach': self.routing_number_ach, } wire_payment_text = ( "<strong>Wire payment</strong>:<br />" "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number_wire)s " "Swift Code: %(swift_code)s<br/>" ) % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number_wire': self.routing_number_wire, 'swift_code': self.swift_code, } payment_info2 = Paragraph('\n'.join([ ach_payment_text, wire_payment_text, ]), ParagraphStyle('')) payment_info2.wrapOn(self.canvas, inches(4.25), inches(0.9)) payment_info2.drawOn(self.canvas, inches(0.7), inches(0.4))
class PylinacCanvas: def __init__(self, filename: str, page_title: str, font: str="Helvetica", metadata: dict=None): self.canvas = Canvas(filename, pagesize=A4) self._font = font self._title = page_title self._generate_pylinac_template_theme() self._add_metadata(metadata) def add_new_page(self, metadata: dict=None): self.canvas.showPage() self._generate_pylinac_template_theme() self._add_metadata(metadata) def _add_metadata(self, metadata: dict=None): if metadata is None: return else: text = ['Metadata:'] for key, value in metadata.items(): text.append(f"{key}: {value}") date = datetime.now().strftime("%A, %B %d, %Y") text.append('Analyzed on: {}'.format(date)) self.add_text(text=text, location=(2, 25.5)) def _generate_pylinac_template_theme(self): # draw logo and header separation line self.canvas.drawImage(osp.join(osp.dirname(osp.dirname(osp.abspath(__file__))), 'files', 'Pylinac Full cropped.png'), 1 * cm, 26.5 * cm, width=5 * cm, height=3 * cm, preserveAspectRatio=True) self.canvas.line(1 * cm, 26.5 * cm, 20 * cm, 26.5 * cm) # draw title self.add_text(text=self._title, location=(7, 28.5), font_size=24) # draw "generated by" tag self.add_text(f"Generated with Pylinac version {__version__}", location=(0.5, 0.5), font_size=8) def add_text(self, text: Union[str, List[str]], location: Sequence, font_size: int=10): """Generic text drawing function. Parameters ---------- location : Sequence of two numbers The first item is the distance from left edge in cm The second item is the distance from bottom edge in cm. text : str, list of strings Text data; if str, prints single line. If list of strings, each list item is printed on its own line. font_size : int Text font size. """ textobj = self.canvas.beginText() textobj.setTextOrigin(location[0]*cm, location[1]*cm) textobj.setFont(self._font, int(font_size)) if isinstance(text, str): textobj.textLine(text) elif isinstance(text, list): for line in text: textobj.textLine(line) self.canvas.drawText(textobj) def add_image(self, image_data: io.BytesIO, location: Sequence, dimensions: Sequence, preserve_aspect_ratio: bool=True): image_data.seek(0) image = ImageReader(Image.open(image_data)) self.canvas.drawImage(image, location[0]*cm, location[1]*cm, width=dimensions[0]*cm, height=dimensions[1]*cm, preserveAspectRatio=preserve_aspect_ratio) def finish(self): self.canvas.showPage() self.canvas.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('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()
#modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; either version 2 #of the License, or (at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ##Contact: [email protected] from reportlab.pdfgen.canvas import Canvas from reportlab.lib.units import cm, mm, inch, pica pdf = Canvas("/home/adam/Desktop/evettetest.pdf") pdf.setFont("Courier", 12) pdf.setStrokeColorRGB(1, 0, 0) text = pdf.beginText(inch * 1, inch * 10) text.textLine("Fog is very handsome.") text.textLine("Moms sucks balls.") pdf.drawText(text) pdf.showPage() pdf.save()
def test0(self): # if they do not have the font files or encoding, go away quietly try: from reportlab.pdfbase.cidfonts import CIDFont, findCMapFile findCMapFile('KSCms-UHC-H') except: #don't have the font pack. return silently return localFontName = 'HYSMyeongJo-Medium' c = Canvas(outputfile('test_multibyte_kor.pdf')) c.setFont('Helvetica', 30) c.drawString(100,700, 'Korean Font Support') c.setFont('Helvetica', 10) c.drawString(100,680, 'Short sample in Unified Hangul Coding (UHC)') hBoxText('\xB9\xD9\xC5\xC1\xC3\xBC (HYSMyeongJo-Medium)', c, 100, 660, 'HYSMyeongJo-Medium', 'KSCms-UHC-H') ## hBoxText('\xB9\xD9\xC5\xC1\xC3\xBC (HYGothic-Medium)', ## c, 100, 640, 'HYGothic-Medium', 'KSCms-UHC-H') pdfmetrics.registerFont(CIDFont('HYSMyeongJo-Medium','KSC-EUC-H')) c.setFont('Helvetica', 10) c.drawString(100,610, "Longer sample From Adobe's Acrobat web page in EUC:") sample = """\xbf\xad \xbc\xf6 \xbe\xf8\xb4\xc2 \xb9\xae\xbc\xad\xb4\xc2 \xbe\xc6\xb9\xab\xb7\xb1 \xbc\xd2\xbf\xeb\xc0\xcc \xbe\xf8\xbd\xc0\xb4\xcf\xb4\xd9. \xbb\xe7\xbe\xf7 \xb0\xe8\xc8\xb9\xbc\xad, \xbd\xba\xc7\xc1\xb7\xb9\xb5\xe5\xbd\xc3\xc6\xae, \xb1\xd7\xb7\xa1\xc7\xc8\xc0\xcc \xb8\xb9\xc0\xcc \xc6\xf7\xc7\xd4\xb5\xc8 \xbc\xd2\xc3\xa5\xc0\xda \xb6\xc7\xb4\xc2 \xc0\xa5 \xbb\xe7\xc0\xcc\xc6\xae\xb8\xa6 \xc0\xdb\xbc\xba\xc7\xcf\xb4\xc2 \xb0\xe6\xbf\xec Adobe\xa2\xe7 Acrobat\xa2\xe7 5.0 \xbc\xd2\xc7\xc1\xc6\xae\xbf\xfe\xbe\xee\xb8\xa6 \xbb\xe7\xbf\xeb\xc7\xd8\xbc\xad \xc7\xd8\xb4\xe7 \xb9\xae\xbc\xad\xb8\xa6 Adobe Portable Document Format (PDF) \xc6\xc4\xc0\xcf\xb7\xce \xba\xaf\xc8\xaf\xc7\xd2 \xbc\xf6 \xc0\xd6\xbd\xc0\xb4\xcf\xb4\xd9. \xb4\xa9\xb1\xb8\xb3\xaa \xb1\xa4\xb9\xfc\xc0\xa7\xc7\xd1 \xc1\xbe\xb7\xf9\xc0\xc7 \xc7\xcf\xb5\xe5\xbf\xfe\xbe\xee\xbf\xcd \xbc\xd2\xc7\xc1\xc6\xae\xbf\xfe\xbe\xee\xbf\xa1\xbc\xad \xb9\xae\xbc\xad\xb8\xa6 \xbf\xad \xbc\xf6 \xc0\xd6\xc0\xb8\xb8\xe7 \xb7\xb9\xc0\xcc\xbe\xc6\xbf\xf4, \xc6\xf9\xc6\xae, \xb8\xb5\xc5\xa9, \xc0\xcc\xb9\xcc\xc1\xf6 \xb5\xee\xc0\xbb \xbf\xf8\xba\xbb \xb1\xd7\xb4\xeb\xb7\xce \xc0\xc7\xb5\xb5\xc7\xd1 \xb9\xd9 \xb4\xeb\xb7\xce \xc7\xa5\xbd\xc3\xc7\xd2 \xbc\xf6 \xc0\xd6\xbd\xc0\xb4\xcf\xb4\xd9. Acrobat 5.0\xc0\xbb \xbb\xe7\xbf\xeb\xc7\xcf\xbf\xa9 \xc0\xa5 \xba\xea\xb6\xf3\xbf\xec\xc0\xfa\xbf\xa1\xbc\xad \xb9\xae\xbc\xad\xb8\xa6 \xbd\xc2\xc0\xce\xc7\xcf\xb0\xed \xc1\xd6\xbc\xae\xc0\xbb \xc3\xdf\xb0\xa1\xc7\xcf\xb4\xc2 \xb9\xe6\xbd\xc4\xc0\xb8\xb7\xce \xb1\xe2\xbe\xf7\xc0\xc7 \xbb\xfd\xbb\xea\xbc\xba\xc0\xbb \xc7\xe2\xbb\xf3\xbd\xc3\xc5\xb3 \xbc\xf6 \xc0\xd6\xbd\xc0\xb4\xcf\xb4\xd9. \xc0\xfa\xc0\xdb\xb1\xc7 © 2001 Adobe Systems Incorporated. \xb8\xf0\xb5\xe7 \xb1\xc7\xb8\xae\xb0\xa1 \xba\xb8\xc8\xa3\xb5\xcb\xb4\xcf\xb4\xd9. \xbb\xe7\xbf\xeb\xc0\xda \xbe\xe0\xb0\xfc \xbf\xc2\xb6\xf3\xc0\xce \xbb\xe7\xbf\xeb\xc0\xda \xba\xb8\xc8\xa3 \xb1\xd4\xc1\xa4 Adobe\xc0\xc7 \xc0\xe5\xbe\xd6\xc0\xda \xc1\xf6\xbf\xf8 \xbc\xd2\xc7\xc1\xc6\xae\xbf\xfe\xbe\xee \xba\xd2\xb9\xfd \xc0\xcc\xbf\xeb \xb9\xe6\xc1\xf6 """ tx = c.beginText(100,600) tx.setFont('HYSMyeongJo-Medium-KSC-EUC-H', 7, 8) tx.textLines(sample) tx.setFont('Helvetica', 10, 12) tx.textLine() tx.textLines("""This test document shows Korean output from the Reportlab PDF Library. You may use one Korean font, HYSMyeongJo-Medium, and a number of different encodings. The available encoding names (with comments from the PDF specification) are: encodings_kor = [ 'KSC-EUC-H', # KS X 1001:1992 character set, EUC-KR encoding 'KSC-EUC-V', # Vertical version of KSC-EUC-H 'KSCms-UHC-H', # Microsoft Code Page 949 (lfCharSet 0x81), KS X 1001:1992 #character set plus 8,822 additional hangul, Unified Hangul #Code (UHC) encoding 'KSCms-UHC-V', #Vertical version of KSCms-UHC-H 'KSCms-UHC-HW-H', #Same as KSCms-UHC-H, but replaces proportional Latin # characters with halfwidth forms 'KSCms-UHC-HW-V', #Vertical version of KSCms-UHC-HW-H 'KSCpc-EUC-H', #Macintosh, KS X 1001:1992 character set with MacOS-KH #extensions, Script Manager Code 3 'UniKS-UCS2-H', #Unicode (UCS-2) encoding for the Adobe-Korea1 character collection 'UniKS-UCS2-V' #Vertical version of UniKS-UCS2-H ] The following pages show all characters in the KS X 1001:1992 standard, using the encoding 'KSC-EUC-H' above. More characters (a LOT more) are available if you use UHC encoding or the Korean Unicode subset, for which the correct encoding names are also listed above. """) c.drawText(tx) c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() # full kuten chart in EUC c.setFont('Helvetica', 18) c.drawString(72,750, 'Characters available in KS X 1001:1992, EUC encoding') y = 600 for row in range(1, 95): KutenRowCodeChart(row, 'HYSMyeongJo-Medium','KSC-EUC-H').drawOn(c, 72, y) y = y - 125 if y < 50: c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() y = 700 c.save() if VERBOSE: print 'saved '+outputfile('test_multibyte_kor.pdf')
def test0(self): "A basic document drawing some strings" c = Canvas(outputfile('test_multibyte_jpn.pdf')) c.setFont('Helvetica', 30) c.drawString(100,700, 'Japanese Font Support') c.setStrokeColor(colors.red) #unicode font automatically supplies the encoding pdfmetrics.registerFont(UnicodeCIDFont('HeiseiMin-W3')) msg = u'\u6771\u4EAC : Unicode font, unicode input' self.hDraw(c, msg, 'HeiseiMin-W3', 100, 600) msg = u'\u6771\u4EAC : Unicode font, utf8 input'.encode('utf8') self.hDraw(c, msg, 'HeiseiMin-W3', 100, 575) # now try verticals - this is broken, not sure how to make it # work in post Unicode world. pdfmetrics.registerFont(CIDFont('HeiseiMin-W3','90ms-RKSJ-V')) c.setFont('HeiseiMin-W3-90ms-RKSJ-V', 16) c.drawString(450, 650, '\223\214\213\236 vertical Shift-JIS') height = c.stringWidth('\223\214\213\236 vertical Shift-JIS', 'HeiseiMin-W3-90ms-RKSJ-V', 16) c.rect(450-8,650,16,-height) pdfmetrics.registerFont(CIDFont('HeiseiMin-W3','EUC-V')) c.setFont('HeiseiMin-W3-EUC-V', 16) c.drawString(475, 650, '\xC5\xEC\xB5\xFE vertical EUC') height = c.stringWidth('\xC5\xEC\xB5\xFE vertical EUC', 'HeiseiMin-W3-EUC-V', 16) c.rect(475-8,650,16,-height) from reportlab.platypus.paragraph import Paragraph from reportlab.lib.styles import ParagraphStyle jStyle = ParagraphStyle('jtext', fontName='HeiseiMin-W3', fontSize=12, wordWrap="CJK" ) gatwickText = '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99\xe3\x81\x97\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' gatwickText2= '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf<font color=red>\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90</font>\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88<link fg="blue" href="http://www.reportlab.com">\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99</link>\xe3\x81\x97\xe3\x81\xa6<u>\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99</u>\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' c.setFont('HeiseiMin-W3', 12) jPara = Paragraph(gatwickText, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 220) jPara = Paragraph(gatwickText2, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 320) c.setFillColor(colors.purple) tx = c.beginText(100, 200) tx.setFont('Helvetica', 12) tx.textLines("""This document shows sample output in Japanese from the Reportlab PDF library. This page shows the two fonts available and tests our ability to measure the width of glyphs in both horizontal and vertical writing, with proportional and fixed-width characters. The red boxes should be the same width (or height) as the character strings they surround. The next pages show more samples and information. """) c.drawText(tx) c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() c.setFont('Helvetica', 30) c.drawString(100,700, 'Japanese TrueType Font Support') msg = u'\u6771\u4EAC : Unicode font'.encode('utf8') msg2 = u'utf8 input 0123456789 ABCDEF'.encode('utf8') from reportlab.pdfbase.ttfonts import TTFont try: msmincho = TTFont('MS Mincho','msmincho.ttc',subfontIndex=0,asciiReadable=0) fn = ' file=msmincho.ttc subfont 0' except: try: msmincho = TTFont('MS Mincho','msmincho.ttf',asciiReadable=0) fn = 'file=msmincho.ttf' except: #Ubuntu - works on Lucid Lynx if xpdf-japanese installed try: msmincho = TTFont('MS Mincho','ttf-japanese-mincho.ttf') fn = 'file=msmincho.ttf' except: msmincho = None if msmincho is None: c.setFont('Helvetica', 12) c.drawString(100,600, 'Cannot find msmincho.ttf or msmincho.ttc') else: pdfmetrics.registerFont(msmincho) c.setFont('MS Mincho', 30) c.drawString(100,600, msg) c.drawString(100,570, msg2) c.drawString(100,540, fn) if fn.endswith('0'): try: msmincho1 = TTFont('MS Mincho 1','msmincho.ttc',subfontIndex=1,asciiPreload=0) pdfmetrics.registerFont(msmincho1) fn = ' file=msmincho.ttc subfont 1' c.setFont('MS Mincho 1',30) c.drawString(100,500,msg+fn) except: c.setFont('Helvetica',30) c.drawString(100,500,msg) c.drawString(100,470, msg2) c.drawString(100,440, fn) #test a paragraph with CJK and <br/> tags u = u'''<font color=red>\u30ac\u30c8\u30a6\u30a3\u30c3</font><br/><font color=blue>\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a</font><br/>\u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f<br/>\u4e00\u306e\u30db\u30c6\u30eb\u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b\u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4\u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8<br/>\u74b0\u5883\u3092\u5b8c\u5099\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0\u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a\u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8\u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054\u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4\u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599\u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' jPara = Paragraph(u, jStyle) jPara.wrap(300, 500) jPara.drawOn(c, 100, 300) c.showPage() # realistic text sample ## sample = """Adobe Acrobat ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xaa\x8aJ\x82\xa9\x82\xc8\x82\xad\x82\xc4\x8d\xa2\x82\xc1\x82\xbd\x82\xb1\x82\xc6\x82\xcd ##\x82\xa0\x82\xe8\x82\xdc\x82\xb9\x82\xf1\x82\xa9\x81B\x8e\x96\x8b\xc6\x8cv\x89\xe6\x8f\x91\x81A\x89c\x8b\xc6\x83\x8c\x83|\x81[\x83g ##\x81A\x83J\x83^\x83\x8d\x83O\x82\xe2\x83p\x83\x93\x83t\x83\x8c\x83b\x83g\x82\xc8\x82\xc7\x90\xa7\x8d\xec\x95\xa8\x82\xcc\x8e\xed ##\x97\xde\x82\xc9\x82\xa9\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xcdAdobe® Acrobat® 5.0\x82\xf0\x8eg\x82\xc1\x82\xc4Adobe PDF\x81iPortable Document ##Format\x81j\x83t\x83@\x83C\x83\x8b\x82\xc9\x95\xcf\x8a\xb7\x82\xb5\x82\xdc\x82\xb5\x82\xe5\x82\xa4\x81B\x96\xb3\x8f\x9e\x94z\x95z\x82\xcc ##Adobe Acrobat Reader\x82\xf0\x8eg\x82\xa6\x82\xce\x81A\x83n\x81[\x83h\x83E\x83F\x83A\x81A\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc9\x82\xa9 ##\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A\x92N\x82\xc5\x82\xe0\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xf0 ##\x83I\x83\x8a\x83W\x83i\x83\x8b\x82\xcc\x91\xcc\x8d\xd9\x82\xc5\x8aJ\x82\xad\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x88\xd3\x90}\x82\xb5\x82\xbd\x82\xc6\x82\xa8\x82\xe8\x82\xc9\x8f\xee\x95\xf1\x82\xf0\x93`\x82\xa6\x82\xe9 ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xb3\x82\xe7\x82\xc9\x81AAdobe Acrobat 5.0\x82\xc5\x82\xcd\x81AWeb\x83u\x83\x89\x83E\x83U\x82\xa9\x82\xe7\x83R\x83\x81\x83\x93\x83g\x82\xe2 ##\x83}\x81[\x83N\x83A\x83b\x83v\x82\xf0\x8f\x91\x82\xab\x8d\x9e\x82\xf1\x82\xbe\x82\xe8\x81A\x93d\x8eq\x8f\x90\x96\xbc\x82\xf0\x8f\x91\x82\xab ##\x8d\x9e\x82\xdd\x81A\x8c\xb4\x96{\x82\xc6\x82\xb5\x82\xc4\x83\x8d\x81[\x83J\x83\x8b\x82\xc9\x95\xdb\x91\xb6\x82\xb7\x82\xe9\x82\xb1\x82\xc6\x82\xe0\x89\xc2\x94\\\x82\xc5\x82\xb7\x81B ##\x8a\xe9\x8b\xc6\x93\xe0\x82\xa0\x82\xe9\x82\xa2\x82\xcd\x8a\xe9\x8b\xc6\x82\xcc\x98g\x82\xf0\x92\xb4\x82\xa6\x82\xc4\x83`\x81[\x83\x80\x82\xc5 ##\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x83\x8f\x81[\x83N\x82\xcc\x90\xb6\x8eY\x90\xab\x82\xf0\x8c\xfc\x8f\xe3\x82\xb3\x82\xb9\x82\xe9\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ## ##Adobe Acrobat 5.0\x82\xc5\x8d\xec\x90\xac\x82\xb5\x82\xbdAdobe PDF\x82\xcd\x81A(Acrobat 5.0\x82\xc5\x82\xcc\x82\xdd\x83T\x83|\x81[\x83g ##\x82\xb5\x82\xc4\x82\xa2\x82\xe9\x88\xc3\x8d\x86\x89\xbb\x90\xdd\x92\xe8\x82\xf0\x8f\x9c\x82\xa2\x82\xc4\x82\xcd)\x8f]\x97\x88\x82\xdc ##\x82\xc5\x82\xcc\x83o\x81[\x83W\x83\x87\x83\x93(3\x82\xa8\x82\xe6\x82\xd1\x82S)\x82\xccAcrobat Reader\x82\xc5\x82\xe0\x8aJ\x82\xad ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B\x8f\xee\x95\xf1\x8b\xa4\x97L\x82\xcc\x83c\x81[\x83\x8b\x82\xc6\x82\xb5 ##\x82\xc4\x81A\x82\xb3\x82\xe7\x82\xc9\x90i\x95\xe0\x82\xb5\x82\xbdAdobe Acrobat 5.0\x82\xf0\x81A\x8f]\x97\x88\x82\xcc\x8a\xc2\x8b\xab ##\x82\xc5\x82\xe0\x88\xc0\x90S\x82\xb5\x82\xc4\x82\xb2\x97\x98\x97p\x82\xa2\x82\xbd\x82\xbe\x82\xaf\x82\xdc\x82\xb7\x81B ## ##\x96{\x90\xbb\x95i\x82\xf0\x83l\x83b\x83g\x83\x8f\x81[\x83N\x82\xc8\x82\xc7\x82\xf0\x89\xee\x82\xb5\x82\xc4\x92\xbc\x90\xda\x82\xa0\x82\xe9 ##\x82\xa2\x82\xcd\x8a\xd4\x90\xda\x82\xc9\x95\xa1\x90\x94\x82\xcc\x92[\x96\x96\x82\xa9\x82\xe7\x8eg\x97p\x82\xb7\x82\xe9\x8f\xea\x8d\x87\x81A ##\x82\xbb\x82\xcc\x92[\x96\x96\x82\xc6\x93\xaf\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xad\x82\xbe ##\x82\xb3\x82\xa2\x81B\x96{\x90\xbb\x95i\x82\xcd\x83N\x83\x89\x83C\x83A\x83\x93\x83g\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc5\x82\xa0\x82\xe8 ##\x81A\x83T\x81[\x83o\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc6\x82\xb5\x82\xc4\x82\xa8\x8eg\x82\xa2\x82\xa2\x82\xbd\x82\xbe\x82\xad\x82\xb1\x82\xc6 ##\x82\xcd\x81A\x8f\xe3\x8bL\x95\xfb\x96@\x82\xc9\x82\xe6\x82\xe9\x88\xc8\x8aO\x81A\x8b\x96\x91\xf8\x82\xb3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb9 ##\x82\xf1\x81B\x95\xa1\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xb3\x82\xea\x82\xe9\x8f\xea\x8d\x87\x82\xc9 ##\x82\xcd\x83\x89\x83C\x83Z\x83\x93\x83X\x83v\x83\x8d\x83O\x83\x89\x83\x80\x82\xf0\x82\xb2\x97\x98\x97p\x82\xc9\x82\xc8\x82\xe9\x82\xc6\x82\xa8\x93\xbe\x82\xc5\x82\xb7\x81B ## ## ##\x81y\x82\xa8\x92m\x82\xe7\x82\xb9\x81zMicrosoft Office XP\x82\xa9\x82\xe7PDF\x82\xf0\x8d\xec\x90\xac\x82\xb7\x82\xe9\x82\xc9\x82\xcd ##""" ## c.setFont('Helvetica', 24) ## c.drawString(100,750, "Sample text from Adobe's web site") ## tx = c.beginText(100,700) ## tx.setFont('Helvetica', 10) ## tx.textLine('Note: line wrapping has not been preserved and some lines may be wrapped in mid-word.') ## tx.textLine('We are just testing that we see Japanese and not random characters!') ## tx.setFont('HeiseiMin-W3-90ms-RKSJ-H',6) ## tx.textLines(sample) ## tx.setFont('Helvetica', 8) ## tx.textLine() ## tx.textLine() ## tx.textLines(""" ## This test document shows Japanese output from the Reportlab PDF Library. ## You may use two fonts, HeiseiMin-W3 and HeiseiKakuGo-W5, and a number of ## different encodings. ## ## The available encoding names (with comments from the PDF specification) are: ## encodings_jpn = [ ## # official encoding names, comments taken verbatim from PDF Spec ## '83pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk6 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## '90ms-RKSJ-H', #Microsoft Code Page 932 (lfCharSet 0x80), JIS X 0208 ## #character set with NEC and IBM extensions ## '90ms-RKSJ-V', #Vertical version of 90ms-RKSJ-H ## '90msp-RKSJ-H', #Same as 90ms-RKSJ-H, but replaces half-width Latin ## #characters with proportional forms ## '90msp-RKSJ-V', #Vertical version of 90msp-RKSJ-H ## '90pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk7 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## 'Add-RKSJ-H', #JIS X 0208 character set with Fujitsu FMR extensions, ## #Shift-JIS encoding ## 'Add-RKSJ-V', #Vertical version of Add-RKSJ-H ## 'EUC-H', #JIS X 0208 character set, EUC-JP encoding ## 'EUC-V', #Vertical version of EUC-H ## 'Ext-RKSJ-H', #JIS C 6226 (JIS78) character set with NEC extensions, ## #Shift-JIS encoding ## 'Ext-RKSJ-V', #Vertical version of Ext-RKSJ-H ## 'H', #JIS X 0208 character set, ISO-2022-JP encoding, ## 'V', #Vertical version of H ## 'UniJIS-UCS2-H', #Unicode (UCS-2) encoding for the Adobe-Japan1 character ## #collection ## 'UniJIS-UCS2-V', #Vertical version of UniJIS-UCS2-H ## 'UniJIS-UCS2-HW-H', #Same as UniJIS-UCS2-H, but replaces proportional Latin ## #characters with half-width forms ## 'UniJIS-UCS2-HW-V' #Vertical version of UniJIS-UCS2-HW-H ## ] ## ## The next few pages show the complete character set available in the encoding ## "90ms-RKSJ-H" - Shift-JIS with the standard Microsoft extensions. ## """) ## c.drawText(tx) ## ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## ## ## ## c.showPage() from reportlab.lib import textsplit c.setFont('HeiseiMin-W3', 14) y = 700 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_START_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica',10) c.drawString(70, y, ' '.join([ascii(x)[4:-1] for x in group])) c.setFont('HeiseiMin-W3', 14) y -= 20 y -= 20 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_END_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica',10) c.drawString(70, y, ' '.join([ascii(x)[2:] for x in group])) c.setFont('HeiseiMin-W3', 14) y -= 20 c.showPage() #utf8 encoded paragraph sample2_uni = u'''\u30ac\u30c8\u30a6\u30a3\u30c3\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a \u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f\u4e00\u306e\u30db\u30c6\u30eb \u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b \u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4 \u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u74b0\u5883\u3092\u5b8c\u5099 \u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0 \u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002 \u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a \u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8 \u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054 \u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4 \u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599 \u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' oneline_uni = u''.join(sample2_uni.split()) sample2_utf8 = oneline_uni.encode('utf8') from reportlab.platypus import Paragraph from reportlab.lib.styles import ParagraphStyle jsty = ParagraphStyle('japanese',fontName='HeiseiMin-W3', wordWrap='CJK') jpara = Paragraph(oneline_uni, style=jsty) c.drawString(100, 710, 'Try to wrap a paragraph using a style with wordWrap="CJK"') w, h = jpara.wrap(400,400) jpara.drawOn(c, 100, 700 - h) #now try to split it... c.drawString(100, 510, 'Now try to split a paragraph as if over a page break') topPara, bottomPara = jpara.split(400, 30) w1, h1 = topPara.wrap(400, 30) topPara.drawOn(c, 100, 450) w2, h2 = bottomPara.wrap(400, 30) bottomPara.drawOn(c, 100, 400) #print 'split into heights %0.2f, %0.2f' % (topPara.height, bottomPara.height) ## c.showPage() ## ## ## # full kuten chart in EUC ## c.setFont('Helvetica', 24) ## c.drawString(72,750, 'Characters available in JIS 0208-1997') ## y = 600 ## for row in range(1, 95): ## KutenRowCodeChart(row, 'HeiseiMin-W3','EUC-H').drawOn(c, 72, y) ## y = y - 125 ## if y < 50: ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## c.showPage() ## y = 700 ## ## c.showPage() #try with Unicode truetype - Mincho for starters ## import time ## started = time.clock() ## c.showPage() ## c.setFont('Helvetica',16) ## c.drawString(100,750, 'About to say Tokyo in MS Gothic...') ## ## from reportlab.pdfbase.ttfonts import TTFont, TTFontFile ## f = TTFontFile("msgothic.ttf") ## print f.name ## ## pdfmetrics.registerFont(TTFont(f.name, f)) ## ## utfText = u'Andr\202'.encode('utf8') ## c.setFont(f.name,16) ## c.drawString(100,700, utfText) ## ## ## #tokyoUCS2 = '\x67\x71\x4E\xAC' ## finished = time.clock() c.save() if VERBOSE: print('saved test_multibyte_jpn.pdf')
class InvoiceTemplate(object): def __init__(self, filename, logo_filename=LOGO_FILENAME, from_address=Address(**settings.INVOICE_FROM_ADDRESS), to_address=None, project_name='', invoice_date=None, invoice_number='', terms=settings.INVOICE_TERMS, due_date=None, date_start=None, date_end=None, bank_name=settings.BANK_NAME, bank_address=Address(**settings.BANK_ADDRESS), account_number=settings.BANK_ACCOUNT_NUMBER, routing_number=settings.BANK_ROUTING_NUMBER, swift_code=settings.BANK_SWIFT_CODE, applied_credit=None, subtotal=None, tax_rate=None, applied_tax=None, total=None): self.canvas = Canvas(filename) self.canvas.setFontSize(DEFAULT_FONT_SIZE) self.logo_filename = os.path.join(os.getcwd(), logo_filename) self.from_address = from_address self.to_address = to_address self.project_name = project_name self.invoice_date = invoice_date self.invoice_number = invoice_number self.terms = terms self.due_date = due_date self.date_start = date_start self.date_end = date_end self.bank_name = bank_name self.bank_address = bank_address self.account_number = account_number self.routing_number = routing_number self.swift_code = swift_code self.applied_credit = applied_credit self.subtotal = subtotal self.tax_rate = tax_rate self.applied_tax = applied_tax self.total = total self.items = [] def add_item(self, description, quantity, unit_cost, subtotal, credits, total): self.items.append(PdfLineItem(description, quantity, unit_cost, subtotal, credits, total)) def get_pdf(self): self.draw_logo() self.draw_from_address() self.draw_to_address() self.draw_project_name() self.draw_statement_period() self.draw_invoice_label() self.draw_details() self.draw_table() self.draw_footer() self.canvas.showPage() self.canvas.save() def draw_logo(self): self.canvas.drawImage(self.logo_filename, inches(0.5), inches(2.5), width=inches(1.5), preserveAspectRatio=True) def draw_text(self, string, x, y): text = self.canvas.beginText() text.setTextOrigin(x, y) for line in string.split('\n'): text.textLine(line) self.canvas.drawText(text) def draw_from_address(self): if self.from_address is not None: self.draw_text(unicode(self.from_address), inches(3), inches(11)) def draw_to_address(self): origin_x = inches(1) origin_y = inches(9.2) self.canvas.translate(origin_x, origin_y) left = inches(0) right = inches(4.5) top = inches(0.3) middle_horizational = inches(0) bottom = inches(-1.7) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, middle_horizational, right - left, top - middle_horizational, fill=1) self.canvas.setFillColorRGB(*BLACK) self.draw_text("Bill To", left + inches(0.2), middle_horizational + inches(0.1)) if self.to_address is not None: self.draw_text(unicode(self.to_address), inches(0.1), inches(-0.2)) self.canvas.translate(-origin_x, -origin_y) def draw_project_name(self): origin_x = inches(1) origin_y = inches(7.4) self.canvas.translate(origin_x, origin_y) left = inches(0) middle_vertical = inches(1) right = inches(4.5) top = inches(0) bottom = inches(-0.3) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, bottom, middle_vertical - left, top - bottom, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawCentredString(midpoint(left, middle_vertical), bottom + inches(0.1), "Project") self.canvas.drawString(middle_vertical + inches(0.2), bottom + inches(0.1), self.project_name) self.canvas.translate(-origin_x, -origin_y) def draw_statement_period(self): origin_x = inches(1) origin_y = inches(6.75) self.canvas.translate(origin_x, origin_y) self.canvas.drawString( 0, 0, "Statement period from %s to %s" % (self.date_start.strftime("%d %B %Y") if self.date_start is not None else "", self.date_end.strftime("%d %B %Y") if self.date_end is not None else "")) self.canvas.translate(-origin_x, -origin_y) def draw_invoice_label(self): self.canvas.setFontSize(size=24) self.canvas.drawString(inches(6.5), inches(10.8), "Invoice") self.canvas.setFontSize(DEFAULT_FONT_SIZE) def draw_details(self): origin_x = inches(5.75) origin_y = inches(9.5) self.canvas.translate(origin_x, origin_y) left = inches(0) right = inches(2) bottom = inches(0) top = inches(1.25) label_height = (top - bottom) / 6.0 label_offset = label_height * 0.8 content_offset = 1.5 * label_offset middle_x = midpoint(left, right) middle_y = midpoint(bottom, top) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(left, middle_y - label_height, right - left, label_height, fill=1) self.canvas.rect(left, top - label_height, right - left, label_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.rect(left, bottom, right - left, top - bottom) self.canvas.rect(left, bottom, 0.5 * (right - left), top - bottom) self.canvas.rect(left, bottom, right - left, 0.5 * (top - bottom)) self.canvas.drawCentredString(midpoint(left, middle_x), top - label_offset, "Date") self.canvas.drawCentredString(midpoint(left, middle_x), top - label_height - content_offset, str(self.invoice_date)) self.canvas.drawCentredString(midpoint(middle_x, right), top - label_offset, "Invoice #") self.canvas.drawCentredString(midpoint(middle_x, right), top - label_height - content_offset, self.invoice_number) self.canvas.drawCentredString(midpoint(left, middle_x), middle_y - label_offset, "Terms") self.canvas.drawCentredString(midpoint(left, middle_x), middle_y - label_height - content_offset, self.terms) self.canvas.drawCentredString(midpoint(middle_x, right), middle_y - label_offset, "Due Date") self.canvas.drawCentredString(midpoint(middle_x, right), middle_y - label_height - content_offset, str(self.due_date)) self.canvas.translate(-origin_x, -origin_y) def draw_table(self): origin_x = inches(0.5) origin_y = inches(6.2) self.canvas.translate(origin_x, origin_y) height = inches(3.5) description_x = inches(2.4) quantity_x = inches(3.15) rate_x = inches(3.9) subtotal_x = inches(5.1) credits_x = inches(6.3) total_x = inches(7.5) header_height = inches(0.3) self.canvas.rect(0, 0, total_x, -height) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(0, 0, total_x, header_height, fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.line(description_x, header_height, description_x, -height) self.canvas.line(quantity_x, header_height, quantity_x, -height) self.canvas.line(rate_x, header_height, rate_x, -height) self.canvas.line(subtotal_x, header_height, subtotal_x, -height) self.canvas.line(credits_x, header_height, credits_x, -height) self.canvas.drawCentredString(midpoint(0, description_x), inches(0.1), "Product") self.canvas.drawCentredString(midpoint(description_x, quantity_x), inches(0.1), "Quantity") self.canvas.drawCentredString(midpoint(quantity_x, rate_x), inches(0.1), "Unit Cost") self.canvas.drawCentredString(midpoint(rate_x, subtotal_x), inches(0.1), "Subtotal") self.canvas.drawCentredString(midpoint(subtotal_x, credits_x), inches(0.1), "Credits Applied") self.canvas.drawCentredString(midpoint(credits_x, total_x), inches(0.1), "Total") coord_y = 0 for item_index in range(len(self.items)): if coord_y < -height: raise InvoiceError("Cannot fit line items on invoice") item = self.items[item_index] description = Paragraph(item.description, ParagraphStyle('', fontSize=12, )) description.wrapOn(self.canvas, description_x - inches(0.2), -header_height) coord_y -= description.height + inches(0.05) description.drawOn(self.canvas, inches(0.1), coord_y) self.canvas.drawCentredString( midpoint(description_x, quantity_x), coord_y, str(item.quantity) ) self.canvas.drawCentredString( midpoint(quantity_x, rate_x), coord_y, get_money_str(item.unit_cost) ) self.canvas.drawCentredString( midpoint(rate_x, subtotal_x), coord_y, get_money_str(item.subtotal) ) self.canvas.drawCentredString( midpoint(subtotal_x, credits_x), coord_y, get_money_str(item.credits) ) self.canvas.drawCentredString( midpoint(credits_x, total_x), coord_y, get_money_str(item.total) ) coord_y -= inches(0.1) self.canvas.line(0, coord_y, total_x, coord_y) self.canvas.translate(-origin_x, -origin_y) def draw_footer(self): self.canvas.rect(inches(0.75), inches(1.3), inches(4), inches(0.5)) self.canvas.setFillColorRGB(*LIGHT_GRAY) self.canvas.rect(inches(5), inches(1.05), inches(3), inches(0.5), fill=1) self.canvas.setFillColorRGB(*BLACK) self.canvas.drawString(inches(5.6), inches(2.45), "Subtotal:") self.canvas.drawString(inches(5.6), inches(2.15), "Tax (%s%%):" % get_money_str(self.tax_rate)) self.canvas.drawString(inches(5.6), inches(1.85), "Credit:") self.canvas.drawString(inches(5.2), inches(1.25), "Total:") self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.45), get_money_str(self.subtotal)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(2.15), get_money_str(self.applied_tax)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.85), get_money_str(self.applied_credit)) self.canvas.drawCentredString(midpoint(inches(7.0), inches(8.0)), inches(1.25), get_money_str(self.total)) self.canvas.drawString(inches(5), inches(0.8), "Thank you for using CommCare HQ.") footer_text = ("Payable by check or wire transfer. " "Wire transfer is preferred: " "Bank: %(bank_name)s " "Bank Address: %(bank_address)s " "Account Number: %(account_number)s " "Routing Number or ABA: %(routing_number)s " "Swift Code: %(swift_code)s") % { 'bank_name': self.bank_name, 'bank_address': self.bank_address, 'account_number': self.account_number, 'routing_number': self.routing_number, 'swift_code': self.swift_code, } payment_info = Paragraph(footer_text, ParagraphStyle('')) payment_info.wrapOn(self.canvas, inches(4), inches(0.9)) payment_info.drawOn(self.canvas, inches(0.75), inches(0.6))
class PDFCreator(object): appName = "txt2pdf (version 1.0)" def __init__(self, args, margins): pageWidth, pageHeight = reportlab.lib.pagesizes.__dict__[args.media] if args.landscape: pageWidth, pageHeight = reportlab.lib.pagesizes.landscape( (pageWidth, pageHeight)) self.author = args.author self.title = args.title self.keywords = args.keywords self.subject = args.subject self.canvas = Canvas(args.output, pagesize=(pageWidth, pageHeight)) self.canvas.setCreator(self.appName) if len(args.author) > 0: self.canvas.setAuthor(args.author) if len(args.title) > 0: self.canvas.setTitle(args.title) if len(args.subject) > 0: self.canvas.setSubject(args.subject) if len(args.keywords) > 0: self.canvas.setKeywords(args.keywords) self.fontSize = args.font_size if args.font not in ('Courier'): self.font = 'myFont' pdfmetrics.registerFont(TTFont('myFont', args.font)) else: self.font = args.font self.kerning = args.kerning self.margins = margins self.leading = (args.extra_vertical_space + 1.2) * self.fontSize self.linesPerPage = int( (self.leading + pageHeight - margins.top - margins.bottom - self.fontSize) / self.leading) self.lppLen = len(str(self.linesPerPage)) fontWidth = self.canvas.stringWidth( ".", fontName=self.font, fontSize=self.fontSize) self.lineNumbering = args.line_numbers if self.lineNumbering: margins.adjustLeft(fontWidth * (self.lppLen + 2)) contentWidth = pageWidth - margins.left - margins.right self.charsPerLine = int( (contentWidth + self.kerning) / (fontWidth + self.kerning)) self.top = pageHeight - margins.top - self.fontSize self.filename = args.filename self.verbose = not args.quiet self.breakOnBlanks = args.break_on_blanks self.encoding = args.encoding self.pageNumbering = args.page_numbers if self.pageNumbering: self.pageNumberPlacement = \ (pageWidth / 2, margins.bottom / 2) def _process(self, data): flen = os.fstat(data.fileno()).st_size lineno = 0 read = 0 for line in data: lineno += 1 if sys.version_info.major == 2: read += len(line) yield flen == \ read, lineno, line.decode(self.encoding).rstrip('\r\n') else: read += len(line.encode(self.encoding)) yield flen == read, lineno, line.rstrip('\r\n') def _readDocument(self): with open(self.filename, 'r') as data: for done, lineno, line in self._process(data): if len(line) > self.charsPerLine: self._scribble( "Warning: wrapping line %d in %s" % (lineno + 1, self.filename)) while len(line) > self.charsPerLine: yield done, line[:self.charsPerLine] line = line[self.charsPerLine:] yield done, line def _newpage(self): textobject = self.canvas.beginText() textobject.setFont(self.font, self.fontSize, leading=self.leading) textobject.setTextOrigin(self.margins.left, self.top) textobject.setCharSpace(self.kerning) if self.pageNumbering: self.canvas.drawString( self.pageNumberPlacement[0], self.pageNumberPlacement[1], str(self.canvas.getPageNumber())) return textobject def _scribble(self, text): if self.verbose: sys.stderr.write(text + os.linesep) def generate(self): self._scribble( "Writing '%s' with %d characters per " "line and %d lines per page..." % (self.filename, self.charsPerLine, self.linesPerPage) ) if self.breakOnBlanks: pageno = self._generateBob(self._readDocument()) else: pageno = self._generatePlain(self._readDocument()) self._scribble("PDF document: %d pages" % pageno) def _generatePlain(self, data): pageno = 1 lineno = 0 page = self._newpage() for _, line in data: lineno += 1 # Handle form feed characters. (line, pageBreakCount) = re.subn(r'\f', r'', line) if pageBreakCount > 0 and lineno >= args.minimum_page_length: for _ in range(pageBreakCount): self.canvas.drawText(page) self.canvas.showPage() lineno = 0 pageno += 1 page = self._newpage() if args.minimum_page_length > 0: break page.textLine(line) if lineno == self.linesPerPage: self.canvas.drawText(page) self.canvas.showPage() lineno = 0 pageno += 1 page = self._newpage() if lineno > 0: self.canvas.drawText(page) else: pageno -= 1 self.canvas.save() return pageno def _writeChunk(self, page, chunk, lineno): if self.lineNumbering: formatstr = '%%%dd: %%s' % self.lppLen for index, line in enumerate(chunk): page.textLine( formatstr % (lineno - len(chunk) + index + 1, line)) else: for line in chunk: page.textLine(line) def _generateBob(self, data): pageno = 1 lineno = 0 page = self._newpage() chunk = list() for last, line in data: if lineno == self.linesPerPage: self.canvas.drawText(page) self.canvas.showPage() lineno = len(chunk) pageno += 1 page = self._newpage() lineno += 1 chunk.append(line) if last or len(line.strip()) == 0: self._writeChunk(page, chunk, lineno) chunk = list() if lineno > 0: self.canvas.drawText(page) self.canvas.showPage() else: pageno -= 1 if len(chunk) > 0: page = self._newpage() self.canvas.drawText(page) self.canvas.showPage() pageno += 1 self.canvas.save() return pageno
def test0(self): "A basic document drawing some strings" # if they do not have the Japanese font files, go away quietly from reportlab.pdfbase.cidfonts import CIDFont, findCMapFile enc = 'GB-EUC-H' try: findCMapFile(enc) except: #they don't have the font pack, return silently return pdfmetrics.registerFont(CIDFont('STSong-Light',enc)) c = Canvas(outputfile('test_multibyte_chs.pdf')) c.setFont('Helvetica', 30) c.drawString(100,700, 'Simplified Chinese Font Support') c.setFont('Helvetica', 10) c.drawString(100,680, 'Short sample: "Reportlab is cool!" (or so we are told)') # the two typefaces hBoxText('\xce\xc4\xbd\xa1\xb5\xc3\xb5\xbd\xc1\xcb \xc4\xc7\xd5\xfd\xba\xc3\xb0\xa2 \xce\xd2 \xba\xdc\xcf\xb2\xbb\xb6. Cool!', c, 100, 660, 'STSong-Light', enc) c.setFont('Helvetica', 10) tx = c.beginText(100, 500) tx.textLines(""" This test document shows Simplified Chinese output from the Reportlab PDF Library. You may use one Chinese font, STSong-Light, and a number of different encodings. The available encoding names (with comments from the PDF specification) are: encodings_chs = [ 'GB-EUC-H', # Microsoft Code Page 936 (lfCharSet 0x86), GB 2312-80 # character set, EUC-CN encoding 'GB-EUC-V', # Vertical version of GB-EUC-H 'GBpc-EUC-H', # Macintosh, GB 2312-80 character set, EUC-CN encoding, # Script Manager code 2 'GBpc-EUC-V', # Vertical version of GBpc-EUC-H 'GBK-EUC-H', # Microsoft Code Page 936 (lfCharSet 0x86), GBK character # set, GBK encoding 'GBK-EUC-V', # Vertical version of GBK-EUC-V 'UniGB-UCS2-H', # Unicode (UCS-2) encoding for the Adobe-GB1 # character collection 'UniGB-UCS2-V' # Vertical version of UniGB-UCS2-H. ] The next few pages show the complete character set available in the encoding "GB-EUC-H". This is the GB 2312-80 character set. """) c.drawText(tx) c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() # full kuten chart in EUC c.setFont('Helvetica', 18) c.drawString(72,750, 'Characters available in GB 2312-80, EUC encoding') y = 600 for row in range(1, 95): KutenRowCodeChart(row, 'STSong-Light',enc).drawOn(c, 72, y) y = y - 125 if y < 50: c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() y = 700 c.save() if VERBOSE: print 'saved '+outputfile('test_multibyte_chs.pdf')