# -*- coding: utf-8 -*-
"""
pyboleto.pdf
~~~~~~~~~~~~
Classe Responsável por fazer o output do boleto em pdf usando Reportlab.
:copyright: © 2011 - 2012 by Eduardo Cereto Carvalho
:license: BSD, see LICENSE for more details.
"""
import os
from reportlab.graphics.barcode.common import I2of5
from reportlab.lib.colors import black
from reportlab.lib.pagesizes import A4, landscape as pagesize_landscape
from reportlab.lib.units import mm, cm
from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.pdfgen import canvas
[documentos]class BoletoPDF(object):
"""Geração do Boleto em PDF
Esta classe é responsável por imprimir o boleto em PDF.
Outras classes podem ser implementadas no futuro com a mesma interface,
para fazer output em HTML, LaTeX, ...
Esta classe pode imprimir boletos em formato de carnê (2 boletos por
página) ou em formato de folha cheia.
:param file_descr: Um arquivo ou *file-like* class.
:param landscape: Formato da folha. Usar ``True`` para boleto
tipo carnê.
"""
# pylint: disable=too-many-instance-attributes
def __init__(self, file_descr, landscape=False):
self.width = 190 * mm
self.width_canhoto = 70 * mm
self.height_line = 6.5 * mm
self.space = 2
self.font_size_title = 6
self.font_size_value = 9
self.delta_title = self.height_line - (self.font_size_title + 1)
self.delta_font = self.font_size_value + 1
if landscape:
pagesize = pagesize_landscape(A4)
else:
pagesize = A4
self.pdf_canvas = canvas.Canvas(file_descr, pagesize=pagesize)
self.pdf_canvas.setStrokeColor(black)
def _draw_recibo_sacado_canhoto(self, boleto_dados, x, y):
"""Imprime o Recibo do Sacado para modelo de carnê
:param boleto_dados: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boleto_dados: :class:`pyboleto.data.BoletoData`
:param x: Current X coordinate
:param y: Current Y coordinate
"""
self.pdf_canvas.saveState()
self.pdf_canvas.translate(x, y)
linha_inicial = 12
# Horizontal Lines
self.pdf_canvas.setLineWidth(2)
self.__horizontalLine(0, 0, self.width_canhoto)
self.pdf_canvas.setLineWidth(1)
self.__horizontalLine(0,
(linha_inicial + 0) * self.height_line,
self.width_canhoto)
self.__horizontalLine(0,
(linha_inicial + 1) * self.height_line,
self.width_canhoto)
self.pdf_canvas.setLineWidth(2)
self.__horizontalLine(0,
(linha_inicial + 2) * self.height_line,
self.width_canhoto)
# Vertical Lines
self.pdf_canvas.setLineWidth(1)
self.__verticalLine(self.width_canhoto - (35 * mm),
(linha_inicial + 0) * self.height_line,
self.height_line)
self.__verticalLine(self.width_canhoto - (35 * mm),
(linha_inicial + 1) * self.height_line,
self.height_line)
self.pdf_canvas.setFont('Helvetica-Bold', 6)
self.pdf_canvas.drawRightString(self.width_canhoto,
0 * self.height_line + 3,
'Recibo do Pagador')
# Titles
self.pdf_canvas.setFont('Helvetica', 6)
self.delta_title = self.height_line - (6 + 1)
self.pdf_canvas.drawString(
self.space,
(((linha_inicial + 0) * self.height_line)) + self.delta_title,
'Nosso Número'
)
self.pdf_canvas.drawString(
self.width_canhoto - (35 * mm) + self.space,
(((linha_inicial + 0) * self.height_line)) + self.delta_title,
'Vencimento'
)
self.pdf_canvas.drawString(
self.space,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'Agência/Código Beneficiário'
)
self.pdf_canvas.drawString(
self.width_canhoto - (35 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'Valor Documento'
)
# Values
self.pdf_canvas.setFont('Helvetica', 9)
heigh_font = 9 + 1
valor_documento = self._formataValorParaExibir(
boleto_dados.valor_documento
)
self.pdf_canvas.drawString(
self.space,
(((linha_inicial + 0) * self.height_line)) + self.space,
boleto_dados.format_nosso_numero()
)
self.pdf_canvas.drawString(
self.width_canhoto - (35 * mm) + self.space,
(((linha_inicial + 0) * self.height_line)) + self.space,
boleto_dados.data_vencimento.strftime('%d/%m/%Y')
)
self.pdf_canvas.drawString(
self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
boleto_dados.agencia_conta_cedente
)
self.pdf_canvas.drawString(
self.width_canhoto - (35 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
valor_documento
)
demonstrativo = boleto_dados.demonstrativo[0:12]
for index, value in enumerate(demonstrativo):
self.pdf_canvas.drawString(
2 * self.space,
(linha_inicial - 1) * self.height_line - (index * heigh_font),
value[0:55]
)
self.pdf_canvas.restoreState()
return (self.width_canhoto,
((linha_inicial + 2) * self.height_line))
def _drawReciboSacado(self, boleto_dados, x, y):
"""Imprime o Recibo do Pagador para modelo de página inteira
:param boleto_dados: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boleto_dados: :class:`pyboleto.data.BoletoData`
"""
self.pdf_canvas.saveState()
self.pdf_canvas.translate(x, y)
linha_inicial = 15
# Horizontal Lines
self.pdf_canvas.setLineWidth(1)
self.__horizontalLine(0,
(linha_inicial + 0) * self.height_line,
self.width)
self.__horizontalLine(0,
(linha_inicial + 1) * self.height_line,
self.width)
self.__horizontalLine(0,
(linha_inicial + 2) * self.height_line,
self.width)
self.pdf_canvas.setLineWidth(2)
self.__horizontalLine(0,
(linha_inicial + 3) * self.height_line,
self.width)
# Vertical Lines
self.pdf_canvas.setLineWidth(1)
self.__verticalLine(
self.width - (30 * mm),
(linha_inicial + 0) * self.height_line,
3 * self.height_line
)
self.__verticalLine(
self.width - (30 * mm) - (35 * mm),
(linha_inicial + 1) * self.height_line,
2 * self.height_line
)
self.__verticalLine(
self.width - (30 * mm) - (35 * mm) - (40 * mm),
(linha_inicial + 1) * self.height_line,
2 * self.height_line
)
# Head
self.pdf_canvas.setLineWidth(2)
self.__verticalLine(40 * mm,
(linha_inicial + 3) * self.height_line,
self.height_line)
self.__verticalLine(60 * mm,
(linha_inicial + 3) * self.height_line,
self.height_line)
if boleto_dados.logo_image:
logo_image_path = load_image(boleto_dados.logo_image)
self.pdf_canvas.drawImage(
logo_image_path,
0, (linha_inicial + 3) * self.height_line + 3,
40 * mm,
self.height_line,
preserveAspectRatio=True,
anchor='sw'
)
self.pdf_canvas.setFont('Helvetica-Bold', 18)
self.pdf_canvas.drawCentredString(
50 * mm,
(linha_inicial + 3) * self.height_line + 3,
boleto_dados.codigo_dv_banco
)
self.pdf_canvas.setFont('Helvetica-Bold', 11.5)
self.pdf_canvas.drawRightString(
self.width,
(linha_inicial + 3) * self.height_line + 3,
'Recibo do Pagador'
)
# Titles
self.pdf_canvas.setFont('Helvetica', 6)
self.delta_title = self.height_line - (6 + 1)
self.pdf_canvas.drawRightString(
self.width,
self.height_line,
'Autenticação Mecânica'
)
self.pdf_canvas.drawString(
0,
(((linha_inicial + 2) * self.height_line)) + self.delta_title,
'Beneficiário'
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) - (40 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.delta_title,
'Agência/Código Beneficiário'
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.delta_title,
'CPF/CNPJ Beneficiário'
)
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.delta_title,
'Vencimento'
)
self.pdf_canvas.drawString(
0,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'Pagador')
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) - (40 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'Nosso Número')
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'N. do documento')
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.delta_title,
'Data Documento'
)
self.pdf_canvas.drawString(
0,
(((linha_inicial + 0) * self.height_line)) + self.delta_title,
'Endereço Beneficiário'
)
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 0) * self.height_line)) + self.delta_title,
'Valor Documento'
)
self.pdf_canvas.drawString(
0,
(((linha_inicial + 0) * self.height_line - 3 * cm)) +
self.delta_title,
'Demonstrativo'
)
# Values
self.pdf_canvas.setFont('Helvetica', 9)
heigh_font = 9 + 1
self.pdf_canvas.drawString(
0 + self.space,
(((linha_inicial + 2) * self.height_line)) + self.space,
boleto_dados.cedente
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) - (40 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.space,
boleto_dados.agencia_conta_cedente
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.space,
boleto_dados.cedente_documento
)
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 2) * self.height_line)) + self.space,
boleto_dados.data_vencimento.strftime('%d/%m/%Y')
)
# Take care of long field
sacado0 = boleto_dados.sacado[0]
while (stringWidth(sacado0,
self.pdf_canvas._fontname,
self.pdf_canvas._fontsize
) > 8.4 * cm):
# sacado0 = sacado0[:-2] + u'\u2026'
sacado0 = sacado0[:-4] + u'...'
self.pdf_canvas.drawString(
0 + self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
sacado0
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) - (40 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
boleto_dados.format_nosso_numero()
)
self.pdf_canvas.drawString(
self.width - (30 * mm) - (35 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
boleto_dados.numero_documento
)
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 1) * self.height_line)) + self.space,
boleto_dados.data_documento.strftime('%d/%m/%Y')
)
valor_documento = self._formataValorParaExibir(
boleto_dados.valor_documento
)
self.pdf_canvas.drawString(
0 + self.space,
(((linha_inicial + 0) * self.height_line)) + self.space,
boleto_dados.cedente_endereco
)
self.pdf_canvas.drawString(
self.width - (30 * mm) + self.space,
(((linha_inicial + 0) * self.height_line)) + self.space,
valor_documento
)
self.pdf_canvas.setFont('Courier', 9)
demonstrativo = boleto_dados.demonstrativo[0:25]
for i in range(len(demonstrativo)):
self.pdf_canvas.drawString(
2 * self.space,
(-3 * cm + ((linha_inicial + 0) * self.height_line)) -
(i * heigh_font),
demonstrativo[i])
self.pdf_canvas.setFont('Helvetica', 9)
self.pdf_canvas.restoreState()
return (self.width, ((linha_inicial + 3) * self.height_line))
def _drawHorizontalCorteLine(self, x, y, width):
self.pdf_canvas.saveState()
self.pdf_canvas.translate(x, y)
self.pdf_canvas.setLineWidth(1)
self.pdf_canvas.setDash(1, 2)
self.__horizontalLine(0, 0, width)
self.pdf_canvas.restoreState()
def _drawVerticalCorteLine(self, x, y, height):
self.pdf_canvas.saveState()
self.pdf_canvas.translate(x, y)
self.pdf_canvas.setLineWidth(1)
self.pdf_canvas.setDash(1, 2)
self.__verticalLine(0, 0, height)
self.pdf_canvas.restoreState()
def _drawReciboCaixa(self, boleto_dados, x, y):
"""Imprime o Recibo do Caixa
:param boleto_dados: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boleto_dados: :class:`pyboleto.data.BoletoData`
"""
self.pdf_canvas.saveState()
self.pdf_canvas.translate(x, y)
# De baixo para cima posicao 0,0 esta no canto inferior esquerdo
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
y = 1.5 * self.height_line
self.pdf_canvas.drawRightString(
self.width,
(1.5 * self.height_line) + self.delta_title - 1,
'Autenticação Mecânica / Ficha de Compensação'
)
# Primeira linha depois do codigo de barra
y += self.height_line
self.pdf_canvas.setLineWidth(2)
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.space, 'Código de baixa'
)
self.pdf_canvas.drawString(0, y + self.space, 'Pagador / Avalista')
y += self.height_line
self.pdf_canvas.drawString(0, y + self.delta_title, 'Nome do Pagador')
sacado = boleto_dados.sacado
# Linha grossa dividindo o Sacado
y += self.height_line
self.pdf_canvas.setLineWidth(2)
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
for i in range(len(sacado)):
self.pdf_canvas.drawString(
25 * mm,
(y - 10) - (i * self.delta_font),
sacado[i]
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha vertical limitando todos os campos da direita
self.pdf_canvas.setLineWidth(1)
self.__verticalLine(self.width - (45 * mm), y, 9 * self.height_line)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(=) Valor cobrado'
)
# Campos da direita
y += self.height_line
self.__horizontalLine(self.width - (45 * mm), y, 45 * mm)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(+) Outros acréscimos'
)
y += self.height_line
self.__horizontalLine(self.width - (45 * mm), y, 45 * mm)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(+) Mora/Multa'
)
y += self.height_line
self.__horizontalLine(self.width - (45 * mm), y, 45 * mm)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(-) Outras deduções'
)
y += self.height_line
self.__horizontalLine(self.width - (45 * mm), y, 45 * mm)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(-) Descontos/Abatimentos'
)
self.pdf_canvas.drawString(
0,
y + self.delta_title,
'Instruções (Informações de responsabilidade do beneficiário)'
)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
instrucoes = boleto_dados.instrucoes
for i in range(len(instrucoes)):
self.pdf_canvas.drawString(
2 * self.space,
y - (i * self.delta_font),
instrucoes[i]
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha horizontal com primeiro campo Uso do Banco
y += self.height_line
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.drawString(0, y + self.delta_title, 'Uso do banco')
self.__verticalLine((30) * mm, y, 2 * self.height_line)
self.pdf_canvas.drawString(
(30 * mm) + self.space,
y + self.delta_title,
'Carteira'
)
self.__verticalLine((30 + 20) * mm, y, self.height_line)
self.pdf_canvas.drawString(
((30 + 20) * mm) + self.space,
y + self.delta_title,
'Espécie'
)
self.__verticalLine(
(30 + 20 + 20) * mm,
y,
2 * self.height_line
)
self.pdf_canvas.drawString(
((30 + 40) * mm) + self.space,
y + self.delta_title,
'Quantidade'
)
self.__verticalLine(
(30 + 20 + 20 + 20 + 20) * mm, y, 2 * self.height_line)
self.pdf_canvas.drawString(
((30 + 40 + 40) * mm) + self.space, y + self.delta_title, 'Valor')
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'(=) Valor documento'
)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
self.pdf_canvas.drawString(
(30 * mm) + self.space,
y + self.space,
boleto_dados.carteira
)
self.pdf_canvas.drawString(
((30 + 20) * mm) + self.space,
y + self.space,
boleto_dados.especie
)
self.pdf_canvas.drawString(
((30 + 20 + 20) * mm) + self.space,
y + self.space,
boleto_dados.quantidade
)
valor = self._formataValorParaExibir(boleto_dados.valor)
self.pdf_canvas.drawString(
((30 + 20 + 20 + 20 + 20) * mm) + self.space,
y + self.space,
valor
)
valor_documento = self._formataValorParaExibir(
boleto_dados.valor_documento
)
self.pdf_canvas.drawRightString(
self.width - 2 * self.space,
y + self.space,
valor_documento
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha horizontal com primeiro campo Data documento
y += self.height_line
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.drawString(
0,
y + self.delta_title,
'Data do documento'
)
self.pdf_canvas.drawString(
(30 * mm) + self.space,
y + self.delta_title,
'N. do documento'
)
self.pdf_canvas.drawString(
((30 + 40) * mm) + self.space,
y + self.delta_title,
'Espécie doc'
)
self.__verticalLine(
(30 + 20 + 20 + 20) * mm,
y,
self.height_line
)
self.pdf_canvas.drawString(
((30 + 40 + 20) * mm) + self.space,
y + self.delta_title,
'Aceite'
)
self.pdf_canvas.drawString(
((30 + 40 + 40) * mm) + self.space,
y + self.delta_title,
'Data processamento'
)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'Nosso número'
)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
self.pdf_canvas.drawString(
0,
y + self.space,
boleto_dados.data_documento.strftime('%d/%m/%Y')
)
self.pdf_canvas.drawString(
(30 * mm) + self.space,
y + self.space,
boleto_dados.numero_documento
)
self.pdf_canvas.drawString(
((30 + 40) * mm) + self.space,
y + self.space,
boleto_dados.especie_documento
)
self.pdf_canvas.drawString(
((30 + 40 + 20) * mm) + self.space,
y + self.space,
boleto_dados.aceite
)
self.pdf_canvas.drawString(
((30 + 40 + 40) * mm) + self.space,
y + self.space,
boleto_dados.data_processamento.strftime('%d/%m/%Y')
)
self.pdf_canvas.drawRightString(
self.width - 2 * self.space,
y + self.space,
boleto_dados.format_nosso_numero()
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha horizontal com primeiro campo Cedente
y += self.height_line
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.drawString(0, y + self.delta_title, 'Beneficiário')
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'Agência/Código Beneficiário'
)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
self.pdf_canvas.drawString(0, y + self.space, boleto_dados.cedente)
self.pdf_canvas.drawRightString(
self.width - 2 * self.space,
y + self.space,
boleto_dados.agencia_conta_cedente
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha horizontal com primeiro campo Local de Pagamento
y += self.height_line
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.drawString(
0,
y + self.delta_title,
'Local de pagamento'
)
self.pdf_canvas.drawString(
self.width - (45 * mm) + self.space,
y + self.delta_title,
'Vencimento'
)
self.pdf_canvas.setFont('Helvetica', self.font_size_value)
self.pdf_canvas.drawString(
0,
y + self.space,
boleto_dados.local_pagamento
)
self.pdf_canvas.drawRightString(
self.width - 2 * self.space,
y + self.space,
boleto_dados.data_vencimento.strftime('%d/%m/%Y')
)
self.pdf_canvas.setFont('Helvetica', self.font_size_title)
# Linha grossa com primeiro campo logo tipo do banco
self.pdf_canvas.setLineWidth(3)
y += self.height_line
self.__horizontalLine(0, y, self.width)
self.pdf_canvas.setLineWidth(2)
self.__verticalLine(40 * mm, y, self.height_line) # Logo Tipo
self.__verticalLine(60 * mm, y, self.height_line) # Numero do Banco
if boleto_dados.logo_image:
logo_image_path = load_image(boleto_dados.logo_image)
self.pdf_canvas.drawImage(
logo_image_path,
0,
y + self.space + 1,
40 * mm,
self.height_line,
preserveAspectRatio=True,
anchor='sw'
)
self.pdf_canvas.setFont('Helvetica-Bold', 18)
self.pdf_canvas.drawCentredString(
50 * mm,
y + 2 * self.space,
boleto_dados.codigo_dv_banco
)
self.pdf_canvas.setFont('Helvetica-Bold', 11.5)
self.pdf_canvas.drawRightString(
self.width,
y + 2 * self.space,
boleto_dados.linha_digitavel
)
# Codigo de barras
self._codigoBarraI25(boleto_dados.barcode, 8 * self.space, 0)
self.pdf_canvas.restoreState()
return self.width, (y + self.height_line)
[documentos] def drawBoletoCarneDuplo(self, boletoDados1, boletoDados2=None):
"""Imprime um boleto tipo carnê com 2 boletos por página.
:param boletoDados1: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:param boletoDados2: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boletoDados1: :class:`pyboleto.data.BoletoData`
:type boletoDados2: :class:`pyboleto.data.BoletoData`
"""
y = 5 * mm
d = self.drawBoletoCarne(boletoDados1, y)
y += d[1] + 6 * mm
# self._drawHorizontalCorteLine(0, y, d[0])
y += 7 * mm
if boletoDados2:
self.drawBoletoCarne(boletoDados2, y)
[documentos] def drawBoletoCarne(self, boleto_dados, y):
"""Imprime apenas dos boletos do carnê.
Esta função não deve ser chamada diretamente, ao invés disso use a
drawBoletoCarneDuplo.
:param boleto_dados: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boleto_dados: :class:`pyboleto.data.BoletoData`
"""
x = 15 * mm
d = self._draw_recibo_sacado_canhoto(boleto_dados, x, y)
x += d[0] + 8 * mm
self._drawVerticalCorteLine(x, y, d[1])
x += 8 * mm
d = self._drawReciboCaixa(boleto_dados, x, y)
x += d[0]
return x, d[1]
[documentos] def drawBoleto(self, boleto_dados):
"""Imprime Boleto Convencional
Você pode chamar este método diversas vezes para criar um arquivo com
várias páginas, uma por boleto.
:param boleto_dados: Objeto com os dados do boleto a ser preenchido.
Deve ser subclasse de :class:`pyboleto.data.BoletoData`
:type boleto_dados: :class:`pyboleto.data.BoletoData`
"""
x = 9 * mm # margem esquerda
y = 10 * mm # margem inferior
self._drawHorizontalCorteLine(x, y, self.width)
y += 4 * mm # distancia entre linha de corte e barcode
d = self._drawReciboCaixa(boleto_dados, x, y)
y += d[1] + (12 * mm) # distancia entre Recibo caixa e linha de corte
self._drawHorizontalCorteLine(x, y, self.width)
y += 20 * mm
d = self._drawReciboSacado(boleto_dados, x, y)
y += d[1]
return (self.width, y)
[documentos] def nextPage(self):
"""Força início de nova página"""
self.pdf_canvas.showPage()
[documentos] def save(self):
"""Fecha boleto e constroi o arquivo"""
self.pdf_canvas.save()
def __horizontalLine(self, x, y, width):
self.pdf_canvas.line(x, y, x + width, y)
def __verticalLine(self, x, y, width):
self.pdf_canvas.line(x, y, x, y + width)
def _formataValorParaExibir(self, nfloat):
if nfloat:
txt = nfloat
txt = txt.replace('.', ',')
else:
txt = ""
return txt
def _codigoBarraI25(self, num, x, y):
"""Imprime Código de barras otimizado para boletos
O código de barras é otmizado para que o comprimeto seja sempre o
estipulado pela febraban de 103mm.
"""
# http://en.wikipedia.org/wiki/Interleaved_2_of_5
altura = 13 * mm
comprimento = 103 * mm
thin_bar = 0.254320987654 * mm # Tamanho correto aproximado
bc = I2of5(num,
barWidth=thin_bar,
ratio=3,
barHeight=altura,
bearers=0,
quiet=0,
checksum=0)
# Recalcula o tamanho do thin_bar para que o cod de barras tenha o
# comprimento correto
thin_bar = (thin_bar * comprimento) / bc.width
bc.__init__(num, barWidth=thin_bar)
bc.drawOn(self.pdf_canvas, x, y)
[documentos]def load_image(logo_image):
"""Load Bank Image"""
pyboleto_dir = os.path.dirname(os.path.abspath(__file__))
image_path = os.path.join(pyboleto_dir, 'media', logo_image)
return image_path